簡體   English   中英

塊中的弱自我

[英]Weak Self in Blocks

我是否需要檢查弱自我是否在塊中為零?

我創建了weakSelf指針,如:

__weak typeof(self) weakSelf = self;

在我做的塊的開頭

if(!weakSelf){return;}

這是不必要的嗎? 或者它取決於我是否正確編碼其余部分,以便當自我死亡時,其他人也會死亡?

這種檢查是不必要的,並且給你一種錯誤的安全感。

這是問題所在:

__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
    if (!weakSelf) { return; }
    // THE LINE OF INTEREST
    [weakSelf doSomething];
});

THE LINE OF INTEREST ,其他一些線程可能會清除對self的最后一個強引用,此時weakSelf設置為nil。 所以doSomething消息被發送到nil,這是“安全的”(它什么都不做),但可能不是你所期望的!

如果你想在weakSelf為零時采取不同的行動, weakSelf ,例如

__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
    if (weakSelf) {
        [weakSelf doSomething];
    } else {
        [someOtherObject doSomethingElse];
    }
});

在這種情況下,在塊驗證weakSelf不是nil的時間和發送doSomething消息的時間之間, weakSelf可能變為nil,並且doSomethingdoSomethingElse都不會實際運行。

正確的解決方案是:

__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
    typeof(self) strongSelf = weakSelf;
    if (strongSelf) {
        [strongSelf doSomething];
    } else {
        [someOtherObject doSomethingElse];
    }
});

在這種情況下,將weakSelf復制到strongSelf (默認情況下很強)是原子的。 如果weakSelf為零,則strongSelf將為零。 如果weakSelf不是nil, strongSelf將不會是nil,並且將成為對象的強引用,防止它在doSomething消息之前被釋放。

這似乎是非常不必要的,因為在nil上調用消息是一種無操作。 (什么都沒發生)

^{
    [weakSelf doSomething]; //Does nothing if weakSelf is nil
}

我認為你可能想要這樣做的唯一原因是不應該調用其他消息(不是自己的)

^{
    // Here I don't want to add weakSelf as an observer if it's nil
    if (!weakSelf) return;

    [OtherClass addObserverForSomething:weakSelf];
}

弱引用不保留引用的對象。 如果沒有其他人保留它,則釋放該對象,並且弱引用指的是nil

因此,您的代碼可能使用引用為nilweakSelf執行。 但這根本沒有理由檢查它。 特別是在Objective-C中,如果發送消息為nil ,則使用已定義的行為。 I. e。 如果使用nil引用設置屬性,它是完美的代碼。 它簡直無處可去。

當然有時候你不想與nil交互。 在這種情況下,你必須檢查它。

順便說一句:你只需要在一些很少的情況下需要weakSelf 這是一個城市傳說,在封閉中一般提到self必須弱,以防止保留周期。 它不是真的,它不是真的,它永遠不會是真的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM