在SDWebImage代码中解释__weak和__strong的使用原因。 __weak和__strong是Objective-C语言中的修饰符。它们主要用于解决循环引用的问题。 在SDWebImage代码中,__weak和__strong被用来修饰对特定对象的引用。__weak用于创建一个弱引用,而__strong用于创建一个强引用。 弱引用是一种非持有引用,即当被引用的对象被释放时,弱引用会自动变为nil。这可以防止循环引用的发生,避免内存泄漏的问题。 强引用是一种持有引用,即当被引用的对象被

13 浏览
0 Comments

在SDWebImage代码中解释__weak和__strong的使用原因。 __weak和__strong是Objective-C语言中的修饰符。它们主要用于解决循环引用的问题。 在SDWebImage代码中,__weak和__strong被用来修饰对特定对象的引用。__weak用于创建一个弱引用,而__strong用于创建一个强引用。 弱引用是一种非持有引用,即当被引用的对象被释放时,弱引用会自动变为nil。这可以防止循环引用的发生,避免内存泄漏的问题。 强引用是一种持有引用,即当被引用的对象被

我认为我很好地理解了强引用和弱引用的关系,但是我不理解下面代码中它们是如何使用的。这段代码来自于Olivier Poitrey在github上提供的SDWebImage。我理解强引用和弱引用的概念如下所述:Explanation of strong and weak storage in iOS5

下面的代码以一种我不太熟悉的方式使用了__weak和__strong关键字。它不是我通常见到的父子关系或委托模式中使用弱引用的方式。然而,我确信这是一个经常使用的模式,因为我在其他代码中也见过类似的用法。它在在另一个线程中的块执行之前设置了一个弱引用。然后,在块内部,它将弱引用设置为强引用。

我确定这是一段好的和优雅的代码,所以我想要理解它。如果在块执行之前"self"不再存在,弱引用将变为零。当块执行时,强引用也将被设置为零。因此,它将知道终止剩余的操作,因为self不再存在。我理解得对吗?

那么,如果我们不使用__weak和__strong关键字会发生什么呢?如果我们在块内部只是检查self == nil。由于块复制了整个树,"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 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);
    }
}

0
0 Comments

在SDWebImage代码中,出现了使用__weak和__strong的原因是为了解决循环引用的问题。具体来说,downloadWithUrl:方法可能需要很长时间执行,而在这个过程中,用户可能会决定离开当前页面,不再需要SDWebImage对象。为了及时清理对象,外部的self引用被声明为weak,这样downloadWithUrl方法就不会阻止SDWebImage对象被释放。

当然,如果你确实需要与self进行操作,你需要一个strong引用。所以,在downloadWithUrl方法的完成回调中,会创建一个strong引用sself来引用self。如果在这个过程中对象被释放了,sself将会是nil。否则,sself将是一个有效的strong引用,表示SDWebImage对象仍然存在,并且对象将在此时完成工作。

另外一个很棒的答案。谢谢nneonneo。

实际上,这不仅仅是为了"方便及时清理对象",它实际上是为了在任何时候都能清理对象 - 否则会出现一个循环引用。self通过关联引用来保留operation,而operation则保留了block。如果block保留了self,就会形成一个循环引用。

因此,使用__weak和__strong的原因在于解决循环引用的问题,避免内存泄漏,并确保对象能够及时释放。这种做法在异步操作中特别有用,可以避免因为对象还在执行任务而导致的一系列问题。

0
0 Comments

在SDWebImage代码中,使用__weak__strong关键字的原因是为了避免引发循环引用的问题。循环引用是指两个或多个对象之间相互持有对方的强引用,导致它们无法被释放,从而造成内存泄漏的情况。

在上面的讨论中,提到了如果在block中直接使用self来判断是否为nil,这样的检查是多余的,因为运行时会将消息发送给nil时直接返回nil。然而,为了避免循环引用的发生,我们需要在block中使用__weak关键字来创建一个弱引用指向self。这样一来,block内部就不会对self进行retain操作,self的引用计数也就不会增加,从而避免了循环引用的问题。

但是,由于block内部不能直接使用弱引用的变量,所以需要在block内部再创建一个强引用指向self。这样一来,就可以确保在整个block的执行过程中,self要么是有效的,要么是nil。通过这种方式,我们可以避免在block执行过程中self被释放,并保证程序的正常执行。

总结起来,使用__weak__strong关键字的目的是为了避免循环引用的发生。通过创建一个弱引用指向self,可以避免在block内部对self进行retain操作,从而避免了循环引用的问题。然后,再通过创建一个强引用指向self,可以确保在block的执行过程中,self要么是有效的,要么是nil,从而保证程序的正常执行。这样一来,就可以确保在整个block的执行过程中,self要么是有效的,要么是nil

0