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/

原文地址:https://www.cnblogs.com/wjw-blog/p/8722176.html

时间: 2024-10-01 11:16:53

weakSelf 运用 strongSelf来解决block的循环引用的相关文章

避免Block的循环引用

避免Block的循环引用 什么是循环引用,什么时候发生循环引用 1 循环引用就是当self 拥有一个block的时候,在block 又调用self的方法.形成你中有我,我中有你,谁都无法将谁释放的困局. self.myBlock = ^{ [self doSomething]; }; +-----------+ +-----------+ | self | | Block | ---> | | --------> | | | retain 2 | <-------- | retain 1

iOS开发Block的介绍以及Block的循环引用问题

1:block的循环引用问题最主要记住两点: 如果[block内部]使用[外部声明的强引用]访问[对象A], 那么[block内部]会自动产生一个[强引用]指向[对象A] 如果[block内部]使用[外部声明的弱引用]访问[对象A], 那么[block内部]会自动产生一个[弱引用]指向[对象A] 2: #import "ViewController.h" #import "XMGPerson.h" @interface ViewController () @prop

IOS中Block的循环引用

@interface DemoObj() @property (nonatomic, strong) NSOperationQueue *queue; @end @implementation DemoObj - (instancetype)init { self = [super init]; if (self) { self.queue = [[NSOperationQueue alloc] init]; } return self; } - (void)dealloc { NSLog(@"

block之---循环引用

block内部引用外界对象的原则:block会对他内部所有的强指针进行强引用. 验证原理: 在主控制器中modal出ModalVC控制器,ModalVC中有强引用的block属性,在block内部使用self,此时ModalVC便不会被释放,不会执行dealloc方法. 验证代码: 循环引用的情况: #import "ModalVC.h" @interface ModalVC () // block属性 @property (nonatomic, strong) void(^block

block 中循环引用的问题

#pragma mark -- 循环引用 //---------------------------------------------------------------------------------------------------- /* 某些block中,使用self会造成循环引用 __weak AppDelegate *weakSelf = self; dispatch_async(mainQueue, ^(void) { AppDelegate *strongSelf = w

防止Block的循环引用

[html] view plaincopyprint? __weak typeof(self)weakSelf=self; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ __strong typeof(weakSelf)strongSelf=weakSelf; [strongSelf doSomething]; }); weak

iOS开发——Block引起循环引用的解决方案

内存问题始终是软件开发中的头等大事,iOS开发中也不例外,在面试中也是必问的问题.今天我们主要来讲讲Block中涉及的循环引用问题.当我们自己一开始写代码的时候,可能会大量在block中使用self,但是当看到别人优秀的代码的时候,发现别人常常不是用self,而使用weakSelf. 为什么呢?本文的示例代码上传至 https://github.com/chenyufeng1991/Block_WeakSelf . 首先我先来说说内存管理的原则: 1.默认使用strong,可选weak.stro

Block的循环引用详解

1.首先我们创建了一个网络请求工具类 然后storyboard里面去创建了一个导航控制器 并且把它设置为初始控制器   然后拖入一个bar button  --show--到自带的控制器 这个时候运行代码的结果是 x 显然这个时候没有造成循环引用 为什么呢?????????????????? //没有self的时候是没有循环引用的 //tools是一个局部的变量 执行完了就会被释放掉了 //这个时候出现了self没有出现循环引用  控制器也被释放了 //block是右边的finished  fi

解决ARC的循环引用问题

看看下面的程序有什么问题: BNRItem.h @interface BNRItem : NSObject @property (nonatomic, strong) BNRItem *containedItem; @property (nonatomic, strong) BNRItem *container; ... @end BNRItem.m #import "BNRItem.h" @implementation BNRItem ... - (void)setContained