默认情况下,block是存档在栈中,可能被随时回收,需要copy操作。这也就是我们在定义block的时候用的是copy,而不是weak等等。
来看下面这个block定义:
// 默认是放在栈中,可能会被随时销毁
void (^blockName)() = ^{
};
// 进行一次copy操作,就可以放在堆中了。
// [blockName copy];
// 以下方法也一样。但是只能在非ARC中使用。
// Block_copy(blockName);
// 用retain没有用的原因:retain只是增加一次计数,block内存还是在栈中,并没有转移到堆中。
再看下面这个block使用:
Person *person = [[Person alloc] init];
person.blockName = ^{
person.age = 20;
};
如果block是copy,并且里面使用它所在的类的对象的话,这个对象永远无法被释放。即person对象在堆中是强指针,且person在blockName就在,而blockName指向的代码也在堆中,即它的person.age=20的那些代码也在堆中,而这些代码中有person对象,所以又反过来指向person对象。就这么在相互指向的,永远不能释放。
解决方法,使用__weak修饰外部变量:
Person *person = [[Person alloc] init];
__weak Person *person0 = person;
person.blockName = ^{
person0.age = 20;
};
网友评论