先将下面访问外部auto对象类型的代码转成c++,使用命令xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc xxx.m -o xxx.cpp
OC代码 C++代码主要是看__main_block_desc_0这个结构体,与之前访问的基本数据类型不同的是多了两个函数指针,访问基本数据类型可以查看之前的文章iOS block访问外部auto、static以及全局(基本数据类型)变量
__main_block_impl_0方法内部会调用_Block_object_assign方法,该方法作用是根据__main_block_impl_0结构体中的p指针的强弱来决定是否对外部对象进行强引用(MRC下的retain操作)
__main_block_dispose_0方法内部会调用_Block_object_dispose方法,该方法的作用对外部对象的引用计数减1(MRC下的release操作),当然,如果是弱引用就不需要减1的操作
如果是对外部对象进行弱引用,生成的c++代码如下:
这次需要指定运行时系统版本以及支持ARC,使用命令:sunell$ xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-8.0.0 xxx.m -o xxx.cpp
OC代码 C++代码__main_block_impl_0结构体中就会生成与之对应的weak类型的指针
再看一下Person释放时机的问题
可以看出当p对象出了{}这作用域后就会调用dealloc方法,如果换成这样
可以看到Person对象在出了作用域后也没有被释放(这里说的额释放有可能不是真正意义上的释放,而只是加入到自动释放池中了,至于什么时候释放由系统决定),而是block被释放后Person对象才被释放,这也就说明了block对Person对象进行了强引用,当block销毁的时候会断掉对Person对象的强引用,这时Person对象的引用计数为0了,就被释放了,如果换成弱引用
可以看到Person对象在出了大括号{}作用域就被释放了,由于block是弱引用指向的Person对象,引用计数并不会加1,如果这个时候调用block访问weakSelf,就是访问了nil,由于weak修饰的对象被释放后会置为nil
网友评论