3 回答

TA貢獻1801條經(jīng)驗 獲得超8個贊
這不僅有助于把重點放在strong或weak討論的一部分。而是專注于循環(huán)部分。
保留周期是當(dāng)對象A保留對象B 而對象B保留對象A 時發(fā)生的循環(huán)。在這種情況下,如果釋放了任何一個對象,則:
因為對象B擁有對它的引用,所以不會釋放對象A。
但是,只要對象A引用了對象B,就永遠不會釋放它。
但是對象A永遠不會被釋放,因為對象B擁有對它的引用。
廣告無限
因此,即使在一切正常的情況下,這兩個對象也應(yīng)該在程序的生命周期內(nèi)徘徊,即使它們在一切正常的情況下也應(yīng)該被釋放。
因此,我們擔(dān)心的是保留周期,而創(chuàng)建這些周期的塊本身沒有任何問題。這不是問題,例如:
[myArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
[self doSomethingWithObject:obj];
}];
該塊保留self,但self不保留該塊。如果釋放一個或另一個,則不會創(chuàng)建任何循環(huán),并且一切都將按應(yīng)有的方式釋放。
您遇到麻煩的地方是這樣的:
//In the interface:
@property (strong) void(^myBlock)(id obj, NSUInteger idx, BOOL *stop);
//In the implementation:
[self setMyBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[self doSomethingWithObj:obj];
}];
現(xiàn)在,您的對象(self)具有strong對該塊的顯式引用。并且該塊具有對的隱式強引用self。這是一個周期,現(xiàn)在兩個對象都不會被正確釋放。
因為在這樣的情況下,self 根據(jù)定義,已經(jīng)有strong對該塊的引用,所以通常最容易解決的方法self是為該塊使用一個顯式的弱引用:
__weak MyObject *weakSelf = self;
[self setMyBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[weakSelf doSomethingWithObj:obj];
}];
但這不應(yīng)該是您在處理調(diào)用塊時遵循的默認模式self!這僅應(yīng)用于打破在self和block之間的保留循環(huán)。如果要在所有地方都采用這種模式,則冒著將塊傳遞給在self釋放后執(zhí)行的操作的風(fēng)險。
//SUSPICIOUS EXAMPLE:
__weak MyObject *weakSelf = self;
[[SomeOtherObject alloc] initWithCompletion:^{
//By the time this gets called, "weakSelf" might be nil because it's not retained!
[weakSelf doSomething];
}];

TA貢獻1772條經(jīng)驗 獲得超5個贊
您不必總是使用弱引用。如果您的塊沒有保留,而是被執(zhí)行然后丟棄,則可以強烈地捕獲自身,因為它不會創(chuàng)建保留周期。在某些情況下,您甚至希望該塊保留自身,直到該塊完成為止,這樣它才不會過早地解除分配。但是,如果您強烈捕獲該塊,并在捕獲自身內(nèi)部,則會創(chuàng)建一個保留周期。

TA貢獻1811條經(jīng)驗 獲得超5個贊
我完全同意@jemmons:
但這不應(yīng)該是您在處理稱為self的塊時遵循的默認模式!這僅應(yīng)用于打破在self和block之間的保留循環(huán)。如果要在所有地方都采用這種模式,則冒著將塊傳遞給在釋放self之后執(zhí)行的操作的風(fēng)險。
//SUSPICIOUS EXAMPLE:
__weak MyObject *weakSelf = self;
[[SomeOtherObject alloc] initWithCompletion:^{
//By the time this gets called, "weakSelf" might be nil because it's not retained!
[weakSelf doSomething];
}];
為了克服這個問題,可以weakSelf在塊內(nèi)部定義一個強引用:
__weak MyObject *weakSelf = self;
[[SomeOtherObject alloc] initWithCompletion:^{
MyObject *strongSelf = weakSelf;
[strongSelf doSomething];
}];
- 3 回答
- 0 關(guān)注
- 576 瀏覽
添加回答
舉報