weakSelf 运用 strongSelf来解决block的循环引用

Posted wjwdive

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了weakSelf 运用 strongSelf来解决block的循环引用相关的知识,希望对你有一定的参考价值。

SDWebImage 中有一段源码:

#if SD_UIKIT
        Class UIApplicationClass = NSClassFromString(@"UIApplication");
        BOOL hasApplication = UIApplicationClass && [UIApplicationClass respondsToSelector:@selector(sharedApplication)];
        if (hasApplication && [self shouldContinueWhenAppEntersBackground]) {
            __weak __typeof__ (self) wself = self;
            UIApplication * app = [UIApplicationClass performSelector:@selector(sharedApplication)];
            self.backgroundTaskId = [app beginBackgroundTaskWithExpirationHandler:^{
                __strong __typeof (wself) sself = wself;

                if (sself) {
                    [sself cancel];

                    [app endBackgroundTask:sself.backgroundTaskId];
                    sself.backgroundTaskId = UIBackgroundTaskInvalid;
                }
            }];
        }
#endif

 

// AFNetworking 中 AFNetworkReachabilityManager.m 的一段代码
__weak __typeof(self)weakSelf = self;
AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
    __strong __typeof(weakSelf)strongSelf = weakSelf;

    strongSelf.networkReachabilityStatus = status;
    if (strongSelf.networkReachabilityStatusBlock) {
        strongSelf.networkReachabilityStatusBlock(status);
    }

};

 

我们用的比较多的 解决循环引用的问题, 在block中 用到对象内部的属性、实例变量的时候要用weakSelf 访问,但是为什么block 内部又用到strongSelf 呢?

大部分情况下,只在block中使用weakSelf 是没有问题的,通常情况下我们只在block中做一个任务,执行完之后回调,但是如果我们要在block中做多个任务,而且第一个任务执行完有可能调用者会释放了self,self = nil, 那么 第二个任务执行时就报错, nil 可以接受任何消息,但是不能发送消息哦??。

  //clang给出的实例代码:
  __weak __typeof__(self) weakSelf = self; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [weakSelf doSomething]; });
//clang 的文档表示,在 doSomething 内,weakSelf 不会被释放。但,下面的情况除外: __weak __typeof__(self) weakSelf = self; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [weakSelf doSomething]; [weakSelf doOtherThing]; });

  

在 doSomething 中,weakSelf 不会变成 nil,不过在 doSomething 执行完成,调用第二个方法 doOtherThing 的时候,weakSelf 有可能被释放,

 //于是,strongSelf 就派上用场了:
    __weak __typeof__(self) weakSelf = self;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        __strong __typeof(self) strongSelf = weakSelf;
        [strongSelf doSomething];
        [strongSelf doOtherThing];
    });

   __strong 确保strongSelf在block中不会被释放。

所以就能理解SDWebImage中的那段代码,block在实现的过程中会对wself进行一次强引用,是为了防止在block还未执行完毕,wself在其他线程中被释放,使得wself为nil。

 

 

https://dhoerl.wordpress.com/2013/04/23/i-finally-figured-out-weakself-and-strongself/

以上是关于weakSelf 运用 strongSelf来解决block的循环引用的主要内容,如果未能解决你的问题,请参考以下文章

weakSelf 和 strongSelf

我是不是需要在块内的 strongSelf = weakSelf 分配上检查 nil ?

iOS 面试题:什么时候在 block 中不需要使用 weakSelf --转自唐巧

iOS 面试题:为什么 weakSelf 需要配合 strong self 使用 --转自唐巧

在swift中使用strongSelf的正确方法是啥?

IOS block 对象强引用和若引用