如题, oc代码如下:
@interface ViewController ()
@property (strong, nonatomic) NSObject *aaaaaaaa;
@property (strong, nonatomic) void(^bbbbbb)(void);
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.bbbbbb = ^{
_aaaaaaaa = [NSObject new];
};
}
@end
依据我们以往对block的内存管理的思考方式:
self 强引用 _bbbbb,而在 _bbbbb 里强引用了_aaaa,按道理是不会造成循环引用的。</br>
而实际上,这会造造成循环引用!
clang后block代码如下(部分)
// block的父类结构体
struct __block_impl {
void *isa;// 有isa指针,就是属于对象范畴
int Flags;
int Reserved;
void *FuncPtr;
};
// viewDidLoad 方法里的第一个blcok
struct __ViewController__viewDidLoad_block_impl_0 {
struct __block_impl impl;// 父
struct __ViewController__viewDidLoad_block_desc_0* Desc;
ViewController *self; // 本结构体“强引用”ViewController *类型的成员变量(self)
// 构造函数
__ViewController__viewDidLoad_block_impl_0(void *fp, struct __ViewController__viewDidLoad_block_desc_0 *desc, ViewController *_self, int flags=0) : self(_self) { // 传进ViewController *_self, 将_self赋值给本结构体里的"self"
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
/// block的描述
static struct __ViewController__viewDidLoad_block_desc_0 {
size_t reserved;
size_t Block_size;
void (*copy)(struct __ViewController__viewDidLoad_block_impl_0*, struct __ViewController__viewDidLoad_block_impl_0*);
void (*dispose)(struct __ViewController__viewDidLoad_block_impl_0*);
} __ViewController__viewDidLoad_block_desc_0_DATA = { 0, sizeof(struct __ViewController__viewDidLoad_block_impl_0), __ViewController__viewDidLoad_block_copy_0, __ViewController__viewDidLoad_block_dispose_0};
由此可见,下划线访问实例变量实际是通过 self->_aaaaaaaa 来访问的,所以代码会造成强引用。