zoukankan      html  css  js  c++  java
  • Block循环引用问题(Objective-c)

    造成循环引用的简单理解是:Block的拥有者在Block作用域内部又引用了自己,因此导致了Block的拥有者永远无法释放内存,就出现了循环引用的内存泄漏

    示例代码

    @interface ObjTest () {
        NSInteger testValue;
    }
    @property (copy, nonatomic) void (^block)();
    @end
    
    @implement ObjTest
    - (void)function {
    /*
        //这里会循环引用
        self.block = ^() {
            self.testValue = 100;
        };
    
    */
    
     __weak ObjTest* weakSelf = self;//使用弱引用,解决循环引用问题
        self.block = ^() {
            weakSelf.testValue = 100;
        };
    
    }
    @end

    再看下面的例子

    #import "networkTool.h"
    
    @implementation networkTool
    
    //定一个block的网络请求
    -(void)loadData:(void (^)(NSString * _Nonnull))finishedBlock{
        //执行网络请求
        //...
        //完成回调返回
        finishedBlock(@"jsonData");
    }
    
    @end
    @interface ViewController ()
    
    @property (nonatomic,strong) networkTool *tool;
    
    @end
    
    @implementation ViewController
    
    - (IBAction)button1Action:(id)sender {
        self.tool=[networkTool new];
        
        [self.tool loadData:^(NSString * _Nonnull jsonData) {
            NSLog(@"接收到请求数据:%@",jsonData);
            self.view.backgroundColor=[UIColor redColor];//此处没有循环引用
        }];
        
    }
    
    - (void)dealloc
    {
        NSLog(@"ViewController -- dealloc");
    }
    
    @end

    他们之间的引用关系 Block引用ViewController,ViewController引用networkTool,但是networkTool没有引用Block,如下图

    下面这样会发生循环引用

    @interface networkTool()
    @property (nonatomic,copy) void(^finishedBlock2)(NSString*);
    @end
    
    @implementation networkTool
    
    //定一个block的网络请求
    -(void)loadData:(void (^)(NSString * _Nonnull))finishedBlock{
        self.finishedBlock2 = finishedBlock;//小心block循环引用
        //执行网络请求
        //...
        //完成回调返回
        finishedBlock(@"jsonData");
    }
    
    @end
    
    //===============ViewController================
    
    @interface ViewController ()
    @property (nonatomic,strong) networkTool *tool;
    @end
    
    @implementation ViewController
    
    - (IBAction)button1Action:(id)sender {
        self.tool=[networkTool new];
        
        //block引起循环引用问题
        [self.tool loadData:^(NSString * _Nonnull jsonData) {
            NSLog(@"接收到请求数据:%@",jsonData);
            self.view.backgroundColor=[UIColor redColor];
        }];
        
    }
    
    - (void)dealloc
    {
        NSLog(@"ViewController -- dealloc");
    }
    
    @end

    上面他们之间的引用关系 Block引用ViewController,ViewController引用networkTool,而且networkTool引用Block

    解决方法:破坏这个闭合的环,如下

    __weak typeof(self) weakSelf=self;
        [self.tool loadData:^(NSString * _Nonnull jsonData) {
            NSLog(@"接收到请求数据:%@",jsonData);
            weakSelf.view.backgroundColor=[UIColor redColor];
        }];
  • 相关阅读:
    致初学者:PHP比ASP优秀的七个理由
    有情人终成眷属为好友hualex2006.12.9结婚祝福
    有情人终成眷属为好友hualex2006.12.9结婚祝福
    各种查找算法效率比较
    实习三 树、二叉树及其应用 (题目:唯一地确定一棵二叉树 )
    hdu 2188 选拔志愿者(博弈)
    hdu 1050Moving Tables(贪心)
    实习一 线性表及其应用 (题目:一元稀疏多项式的加法运算 )
    实习六 农夫过河问题
    实习二 栈、队列和递归算法设计 (题目:停车场管理 )
  • 原文地址:https://www.cnblogs.com/dhui69/p/11162125.html
Copyright © 2011-2022 走看看