在SDWebImage代码中解释__weak和__strong的使用原因

我认为我很了解强和弱的关键字,但我不明白它是如何在下面的代码中使用的。 这个代码是由github上的Olivier Poitrey提供的SDWebImage。 我了解强和弱的关键字,如下所述: iOS5强和弱存储的解释

下面的代码以对我感兴趣的方式使用__weak和__strong关键字。 这是不是一个孩子父母关系或委托模式,因为我习惯于看到弱用。 但是,我确定这是一个经常使用的模式,正如我之前在其他代码中看到的那样。 它在另一个线程上运行的块之前设置__weak引用。 然后,在该块内,它将弱参考设置为强参考。

我敢肯定,这是优雅的代码,所以我试图理解它。 如果在块运行之前“自我”不再存在,则弱自引用将被清零。 块运行时,强参考也将被设置为零。 因此,由于自己不再存在,所以会知道杀死其余的操作。 我有这个对吗?

现在,如果我们不使用__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的完成块对self有很强的参考价值。 如果物体在这个时候消失, sself将是nil 。 否则,这将是一个有效的强引用,表示SDWebImage对象仍然在附近,此时对象将完成其工作。

我敢肯定,这是优雅的代码,所以我试图理解它。 如果在块运行之前“自我”不再存在,则弱自引用将被清零。 块运行时,强参考也将被设置为零。 因此,由于自己不再存在,所以会知道杀死其余的操作。 我有这个对吗?

不,你一直在想这个。 __weak存储限定符就是:限定符。 __weak对象是显式的不存在的,但是如果从一个强variables中分配,它们不会自动设置为nil。 事实上,这将打败一个弱variables的目的!

现在,如果我们不使用__weak和__strong关键字会发生什么? 如果我们只是检查块内部是否self == nil。 自从块复制了整棵树之后,“自我”是不是零?

检查实际上是不必要的,因为运行时将消息parsing为零(但是,稍后可能对实现很重要,谁知道)。 你在这个问题上很有前途:没有那么一点“弱到强”的跳舞,那么自我将被这个块保留下来,有可能造成一个非常糟糕的保留周期。 我可以在哪里开始把这一切联系在一起:

因为我们不希望块保留我们的variables,但是我们也希望它在块的范围内是强壮的,所以没有什么奇怪的事情发生,自己被分配给一个弱指针。 当块发生在我们的弱指针上时,不允许保留它,所以自我的引用计数保持不变,然后一旦在块内部,我们就回到一个强自variables,所以弱块被释放,我们不用再担心了。 实际上,这意味着我们有一个坚实的保证,即在整个项目的执行过程中,自我或者是有价值的,或者是无价值的。 漂亮整洁,是吧?