zoukankan      html  css  js  c++  java
  • ios block常见的错误(二)——循环引用

    这篇博文继续block的常见错误——循环引用。

    循环引用是很多初学者不能察觉的,其产生的原因,是block中的代码会对对象进行强引用

    读者请阅读示例代码1,并思考示例代码1所创建的对象能否被正常销毁?

    示例代码1:

    //DemoObj.m
    
    @interface DemoObj ()
    @property (nonatomic, strong) NSMutableArray *myBlocks;
    @end
    
    #pragma mark 将代码改为调用self的方法
    
    -(NSMutableArray *)myBlocks
    {
        if (_myBlocks == nil) {
            _myBlocks = [NSMutableArray array];
        }
        
        return _myBlocks;
    }
    
    - (instancetype)init
    {
        self = [super init];
        if (self) {
            int(^sum)(int, int) = ^(int x, int y) {
                return [self sum:x y:y];
            };
            [self.myBlocks addObject:sum];
        }
        
        return self;
    }

    -(int)sum:(int) x y:(int)y
    {
        return x + y;
    }
    #pragma mark 对象被释放时自动调用 - (void)dealloc { NSLog(@"DemoObj被释放"); }

    答案是不能正常释放的。读者不妨在xcode中试试。

    产生原因在block代码中出现了self:

    int(^sum)(int, int) = ^(int x, int y) {
        return [self sum:x y:y];
    };

    此时sum的block对self强引用,在加上self对myBlocks强引用:

    @property (nonatomic, strong) NSMutableArray *myBlocks;

    以及sum block被添加到数组时,会被数组强引用:

    [self.myBlocks addObject:sum];

    这三个引用之间形成了循环引用,如下图:

    循环引用的结果就是对象无法被释放!

    碰到这类问题,程序员如何解除循环引用呢?

    有以下几种解决方案:

    1.在block代码中不要引用self以及其他局部变量;如

    int(^sum)(int, int) = ^(int x, int y) {
        return [self sum:x y:y];
    };

    修改成

    int(^sum)(int, int) = ^(int x, int y) {
        return x + y;
    };

    2.使用__weak关键字,可以将局部变量声明为弱引用

    如:

    - (instancetype)init
    {
        self = [super init];
        if (self) {
            int(^sum)(int, int) = ^(int x, int y) {
                return [self sum:x y:y];
            };
            [self.myBlocks addObject:sum];
        }
        
        return self;
    }

    修改为:

    - (instancetype)init
    {
        self = [super init];
        if (self) {
            __weak DemoObj *weakSelf = self;
            int(^sum)(int, int) = ^(int x, int y) {
                return [weakSelf sum:x y:y];
            };
            [self.myBlocks addObject:sum];
        }
        
        return self;
    }

    block的循环引用就说到这,下一篇继续来讲解block的常见错误

  • 相关阅读:
    Daily Scrum NO.4
    Daily Scrum NO.3
    Daily Scrum NO.2
    Daily Scrum NO.1
    Beta任务项录入
    M1事后分析报告
    wenbao与概率
    wenbao与组合数
    wenbao与高斯消元
    wenbao与链表
  • 原文地址:https://www.cnblogs.com/Storms/p/3684215.html
Copyright © 2011-2022 走看看