默認情況下京郑,block是存檔在棧中显押,可能被隨時回收,需要copy操作傻挂。這也就是我們在定義block的時候用的是copy,而不是weak等等挖息。
來看下面這個block定義:
// 默認是放在棧中金拒,可能會被隨時銷毀
void (^blockName)() = ^{
};
// 進行一次copy操作,就可以放在堆中了。
// [blockName copy];
// 以下方法也一樣绪抛。但是只能在非ARC中使用资铡。
// Block_copy(blockName);
// 用retain沒有用的原因:retain只是增加一次計數(shù),block內(nèi)存還是在棧中幢码,并沒有轉移到堆中笤休。
再看下面這個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;
};