[英]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
。 如果對象在這段時間內消失,則sself
將nil
。 否則,它將是有效的強引用,指示SDWebImage
對象仍然存在,並且該對象將在此時完成工作。
我確信這是一個很好的優雅代碼,因此我正在嘗試理解它。 如果在塊運行之前“自我”不存在,則弱自我參考將歸零。 當該塊運行時,強參考也將設置為零。 因此,由於self不再存在,它將知道殺死其余的操作。 我說對了嗎?
不,您已經考慮了很多。 __weak
storage限定詞就是:限定詞。 __weak
對象將顯式保留,但如果從強變量中分配,它們並不會自動設置為nil。 實際上,這將破壞弱變量的目的!
現在,如果我們不使用__weak和__strong關鍵字怎么辦? 如果我們只是在塊內部檢查self == nil怎么辦。 自從該塊復制了整個樹之后,“自我”永遠不會為零嗎?
實際上,檢查是不必要的,因為運行時會將消息解析為nil到nil(但是,這對於以后的實現可能很重要,誰知道)。 您會發現這一點:如果沒有那種“從弱到強”的舞蹈,那么自我就會被障礙物保留,並有可能創造出令人討厭的保留周期。 在這里,我可以將所有這些聯系在一起:
因為我們不希望該塊保留我們的變量,但是我們也希望它在該塊的作用域內更強,所以不會發生任何奇怪的事情,將self分配給一個弱指針。 當該塊發生在我們的弱指針上時,不允許保留它,因此self的引用計數保持不變,然后一旦進入該塊,我們就返回到一個強自變量,從而釋放了弱變量,然后我們不必再擔心了。 實際上,這意味着我們有力保證在整個塊執行過程中,self要么是值,要么是nil。 很整潔吧?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.