關(guān)于OC中Block的實現(xiàn)原理,百度可以搜到一堆。但沒有一篇文章說明__weak修飾的變量是如何被捕獲的為何沒影響到原對象的引用計數(shù)。以下是對這個丟失的部分的補充。
PS:閱讀以下內(nèi)容之前,應(yīng)了解Block和weak的實現(xiàn)原理。
1. 首先,main.m有以下代碼
typedef void(^Block)();
Block block;
int main(int argc, char * argv[]) {
NSObject *obj = [NSObject new];
NSLog(@"%@",[obj valueForKey:@"retainCount"]);
__weak id weakObj = obj;
block = ^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(0, 0), ^{
NSLog(@"weakObj -- %@",[weakObj valueForKey:@"retainCount"]);
});
};
block();
NSLog(@"%@",[obj valueForKey:@"retainCount"]);
sleep(10);
}
2. cd到工程目錄后,clang重寫
clang -rewrite-objc -fobjc-arc -stdlib=libc++ -mmacosx-version-min=10.7 -fobjc-runtime=macosx-10.7 -Wno-deprecated-declarations main.m
3. 打開main.cpp并觀察重寫后的block結(jié)構(gòu)體
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
__weak id weakObj;
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __weak id _weakObj, int flags=0) : weakObj(_weakObj) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
4. 結(jié)論
如果你也注意到了__weak id weakObj;想必已經(jīng)明了。