探究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;想必已经明了。

完。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 《Objective-C高级编程》这本书就讲了三个东西:自动引用计数、block、GCD,偏向于从原理上对这些内容...
    WeiHing阅读 13,340评论 10 69
  • 一、Objective-C发展史 Objective-C从1983年诞生,已经走过了30多年的历程。随着时间的推移...
    没事蹦蹦阅读 11,131评论 12 34
  • 一、定义一个Block 在上面的代码中定义了一个无返回值无参数的block,并定义了一个全局变量globalStr...
    初心丶可曾记阅读 2,593评论 1 3
  • 参考文档1:BlocksRuntime/runtime.c参考文档2:BlocksRuntime/Block_pr...
    破弓阅读 4,357评论 0 4
  • 我以为忘记你 就可以过得很好 我以为不去打扰 你就会很好 我以为 静静的喜欢就好 我想看到你 开开心心就好
    小斑先森阅读 1,414评论 0 0

友情链接更多精彩内容