2014-02-28 42 views
0

我知道有關塊的最佳做法就是這樣塊很強的參考

__weak SomeObjectClass *weakSelf = self; 

SomeBlockType someBlock = ^{ 
    SomeObjectClass *strongSelf = weakSelf; 
    if (strongSelf == nil) { 
     // The original self doesn't exist anymore. 
     // Ignore, notify or otherwise handle this case. 
    } 
    [self someMethod]; 
}; 

我瞭解使用weakSelf是用來防止在weakSelf的情況下保留週期和使用strongSelf可能爲零。 但我只是想知道使用strongSelf可以導致保留週期再次因爲塊捕獲並保留強自己和強自己也是自己的指針。 有人可以給我一個解釋,謝謝。

+0

注:'__weak'指針_can_被用於避免保留週期。但是,即使您在代碼塊中意外使用了_self_,您的代碼也沒有保留週期 - 而不是使用_strongSelf_。 – CouchDeveloper

回答

1

問問自己:strongSelf存在多久?

strongSelf只存在,而塊是執行。所以基本上,它有一個強大的參考,而someMethod正在執行,而不再是。

我假設你的意思

[strongSelf someMethod]; 

,而不是

[self someMethod]; 

因爲前者持有的強引用strongSelf(等於自我),而塊執行而後者將堅持參照自我,而塊存在

+0

這是說,當我使用** strongSelf **限制其範圍時,沒有必要使用** weakSelf **? – passol

-1

首先,你必須瞭解strongSelf的生命週期,它只存在於某個塊中,一些塊完成後,由strongSelf引用的對象將被釋放。 當someBlock翻譯成MRR會喜歡這樣的:

^{ 
    SomeObjectClass *strongSelf = [weakSelf retain]; 
    if (strongSelf == nil) { 
    // The original self doesn't exist anymore. 
    // Ignore, notify or otherwise handle this case. 
    } 
    [self someMethod]; 
    [strongSelf release]; 
}; 
+0

這是說,當我使用** strongSelf **來限制它的範圍時,沒有必要使用** weakSelf **? – passol

+0

@ user3322720,大多數時候你不需要** weakSelf **,但有時你想避免循環引用,那麼你可以編寫像** someBlock **這樣的代碼。 – zhzhy

0

documentation

您可以使用一輩子預選賽避免強烈的參考週期。例如,對於 示例,通常如果您有一個排列在 親子分層結構中的對象圖,並且父母需要引用其子女,並且反之亦然,則可以使父母對子女關係更強壯,並且子對象關係爲 - 親密關係弱。其他情況可能更爲微妙,特別是涉及塊對象時。*

在手動引用計數模式下,__block id x;具有保留x的效果不是 。在ARC模式下,__block id x;默認保留x(就像所有其他值一樣 )。要獲得ARC下的手動引用計數模式 行爲,可以使用__unsafe_unretained __block id x ;. 因爲名稱__unsafe_unretained意味着,但是,有一個 非保留變量是危險的(因爲它可能會晃),因此不鼓勵 。兩個更好的選擇是使用__weak(如果 您不需要支持iOS 4或OS X v10.6),或者將__block 值設置爲零以中斷保留週期。

和SOM更documentation

如果您需要捕獲在一個塊的自我,這樣的定義 回調塊時一樣,它要考慮內存管理 影響是很重要的。

塊保持到任何拍攝對象的強引用,包括 自我,這意味着它很容易具有較強的參考 週期

至於你的例子來結束 - 無保留週期出現,如CouchDeveloper表示,因爲block只會在執行時保持對自身的引用。但會有的,不管你的__weak聲明,如果我們改變代碼如下:

__weak SomeObjectClass *weakSelf = self; 

self.someBlock = ^{ 
    SomeObjectClass *strongSelf = weakSelf; 
    if (strongSelf == nil) { 
     // The original self doesn't exist anymore. 
     // Ignore, notify or otherwise handle this case. 
    } 
    [self someMethod]; 
}; 

現在我們有保留週期 - 我們有參考框和內部的塊中,我們有參考的自我。爲了避免這種情況,你應該使用__weak方法:

__weak SomeObjectClass *weakSelf = self; 

self.someBlock = ^{ 
    SomeObjectClass *strongSelf = weakSelf; 
    if (strongSelf == nil) { 
     // The original self doesn't exist anymore. 
     // Ignore, notify or otherwise handle this case. 
    } else { 
     [strongSelf someMethod]; 
    } 
}; 

一些更多的文章: https://coderwall.com/p/vaj4tg

http://teohm.com/blog/2012/09/03/breaking-arc-retain-cycle-in-objective-c-blocks/