探究Block对weak对象的捕获原理

关于OC中Block的实现原理,百度可以搜到一堆。但没有一篇文章说明__weak修饰的变量是如何被捕获的为何没影响到原对象的引用计数。以下是对这个丢失的部分的补充。

PS:阅读以下内容之前,应了解Block和weak的实现原理。

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结构体
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. 结论

如果你也注意到了__weak id weakObj;想必已经明了。

完。

你可能感兴趣的:(探究Block对weak对象的捕获原理)