默認情況下,block是存檔在棧中,可能被隨時回收,需要copy操作。這也就是我們在定義block的時候用的是copy,而不是weak等等。
來看下面這個block定義:
// 默認是放在棧中,可能會被隨時銷毀
void (^blockName)() = ^{
};
// 進行一次copy操作,就可以放在堆中了。
// [blockName copy];
// 以下方法也一樣。但是只能在非ARC中使用。
// Block_copy(blockName);
// 用retain沒有用的原因:retain只是增加一次計數(shù),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;
};