簡體   English   中英

在SDWebImage代碼中說明__weak和__strong的使用原因

[英]Explain __weak and __strong usage reasons in SDWebImage code

我想我很好地理解了強關鍵字和弱關鍵字,但是我不明白下面代碼中的用法。 這段代碼來自Olivier Poitrey的SDWebImage,可在github上找到。 我了解強弱關鍵字,如下所述: iOS5中強弱存儲的說明

下面的代碼以一種令我感到好奇的方式使用__weak和__strong關鍵字。 這不是孩子-父母關系或委托模式,因為我已經習慣了使用弱者。 但是,我確定這是一種經常使用的模式,就像我之前在其他代碼中所看到的那樣。 它在另一個線程上運行的塊之前設置__weak引用。 然后,在該塊內,將弱參考設置為強參考。

我確信這是一個很好的優雅代碼,因此我正在嘗試理解它。 如果在塊運行之前“自我”不存在,則弱自我參考將歸零。 當該塊運行時,強參考也將設置為零。 因此,由於self不再存在,它將知道殺死其余的操作。 我說對了嗎?

現在,如果我們不使用__weak和__strong關鍵字怎么辦? 如果我們只是在塊內部檢查self == nil怎么辦。 自從該塊復制了整個樹之后,“自我”永遠不會為零嗎?

有人可以幫助揭開這真棒代碼的神秘面紗嗎? 有人可以驗證或否定我的假設嗎?

- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock;
{
    [self cancelCurrentImageLoad];

    self.image = placeholder;

    if (url)
    {
        __weak UIImageView *wself = self;
        id<SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished)
        {
            __strong UIImageView *sself = wself;
            if (!sself) return;
            if (image)
            {
                sself.image = image;
                [sself setNeedsLayout];
            }
            if (completedBlock && finished)
            {
                completedBlock(image, error, cacheType);
            }
        }];
        objc_setAssociatedObject(self, &operationKey, operation, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
}

downloadWithUrl:方法可能需要很長時間。 在那段時間里,用戶可能決定離開,不再需要SDWebImage對象。 為了便於及早清理對象,外部self參考很弱。 這樣, downloadWithUrl不會阻止SDWebImage被釋放

當然,如果您確實想與self一起工作,則需要一個強有力的參考。 因此, downloadWithUrl的on-completion塊強烈引用了self 如果對象在這段時間內消失,則sselfnil 否則,它將是有效的強引用,指示SDWebImage對象仍然存在,並且該對象將在此時完成工作。

我確信這是一個很好的優雅代碼,因此我正在嘗試理解它。 如果在塊運行之前“自我”不存在,則弱自我參考將歸零。 當該塊運行時,強參考也將設置為零。 因此,由於self不再存在,它將知道殺死其余的操作。 我說對了嗎?

不,您已經考慮了很多。 __weak storage限定詞就是:限定詞。 __weak對象將顯式保留,但如果從強變量中分配,它們並不會自動設置為nil。 實際上,這將破壞弱變量的目的!

現在,如果我們不使用__weak和__strong關鍵字怎么辦? 如果我們只是在塊內部檢查self == nil怎么辦。 自從該塊復制了整個樹之后,“自我”永遠不會為零嗎?

實際上,檢查是不必要的,因為運行時會將消息解析為nil到nil(但是,這對於以后的實現可能很重要,誰知道)。 您會發現這一點:如果沒有那種“從弱到強”的舞蹈,那么自我就會被障礙物保留,並有可能創造出令人討厭的保留周期。 在這里,我可以將所有這些聯系在一起:

因為我們不希望該塊保留我們的變量,但是我們也希望它在該塊的作用域內更強,所以不會發生任何奇怪的事情,將self分配給一個弱指針。 當該塊發生在我們的弱指針上時,不允許保留它,因此self的引用計數保持不變,然后一旦進入該塊,我們就返回到一個強自變量,從而釋放了弱變量,然后我們不必再擔心了。 實際上,這意味着我們有力保證在整個塊執行過程中,self要么是值,要么是nil。 很整潔吧?

暫無
暫無

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

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