如題, 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
依據(jù)我們以往對(duì)block的內(nèi)存管理的思考方式:
self 強(qiáng)引用 _bbbbb蒲赂,而在 _bbbbb 里強(qiáng)引用了_aaaa州丹,按道理是不會(huì)造成循環(huán)引用的醋安。</br>
而實(shí)際上,這會(huì)造造成循環(huán)引用墓毒!
clang后block代碼如下(部分)
// block的父類(lèi)結(jié)構(gòu)體
struct __block_impl {
void *isa;// 有isa指針吓揪,就是屬于對(duì)象范疇
int Flags;
int Reserved;
void *FuncPtr;
};
// viewDidLoad 方法里的第一個(gè)blcok
struct __ViewController__viewDidLoad_block_impl_0 {
struct __block_impl impl;// 父
struct __ViewController__viewDidLoad_block_desc_0* Desc;
ViewController *self; // 本結(jié)構(gòu)體“強(qiáng)引用”ViewController *類(lèi)型的成員變量(self)
// 構(gòu)造函數(shù)
__ViewController__viewDidLoad_block_impl_0(void *fp, struct __ViewController__viewDidLoad_block_desc_0 *desc, ViewController *_self, int flags=0) : self(_self) { // 傳進(jìn)ViewController *_self, 將_self賦值給本結(jié)構(gòu)體里的"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};
由此可見(jiàn),下劃線(xiàn)訪(fǎng)問(wèn)實(shí)例變量實(shí)際是通過(guò) self->_aaaaaaaa 來(lái)訪(fǎng)問(wèn)的所计,所以代碼會(huì)造成強(qiáng)引用柠辞。