加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

swift之block的循环引用

发布时间:2020-12-14 01:29:58 所属栏目:百科 来源:网络整理
导读:ViewController #import "ViewController.h"#import "NetworkTools.h"/* 接触循环引用 打破引用循环即可1.不使用成员变量 来调用闭包2.__weak or __unsafe_unretained */@interface ViewController ()@property (nonatomic,strong) NetworkTools *tools;@end

ViewController

#import "ViewController.h"
#import "NetworkTools.h"


/*
 接触循环引用   打破引用循环即可
1.不使用成员变量 来调用闭包
2.__weak or __unsafe_unretained
 */
@interface ViewController ()
@property (nonatomic,strong) NetworkTools *tools;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //加载网络数据
    self.tools = [[NetworkTools alloc] init];
    
    //以后工作中 大家会看到大量以下代码
    //不会有任何不同
    //将一个弱引用的对象 在闭包中变成强引用的对象 希望 在对象self在被回收时  记录self  以便能够继续访问方法
    //但是就是个棒槌  没有任何作用
    __unsafe_unretained typeof(self) weakSelf = self;
    [self.tools loadData:^(NSString *html) {
        __strong typeof(self) strongSelf = weakSelf;
        NSLog(@"data = %@",html);
        NSLog(@"%@",strongSelf.view);
    }];
}

- (void) method2 {
    //加载网络数据
    self.tools = [[NetworkTools alloc] init];
    
    //定义block的时候  在block中使用了外部变量 会默认做copy操作
    //会对self进行强引用
    
    
    ////接触循环引用的方法二
    // __weak 相当于 weak关键字修饰 当对象被回收时  对象地址会自动指向nil  给nil发送消息 在OC中是可以的
    //不会造成野指针访问
    //iOS 5.0之后推出的
    __weak typeof(self) weakSelf = self;
    
    //    __unsafe_unretained typeof(self) weakSelf = self;
    [self.tools loadData:^(NSString *html) {
        NSLog(@"data = %@",html);
        //现在会产生循环引用嘛?
        NSLog(@"%@",weakSelf.view);
    }];
}


- (void) method1 {
    //加载网络数据
    self.tools = [[NetworkTools alloc] init];
    
    //定义block的时候  在block中使用了外部变量 会默认做copy操作
    //会对self进行强引用
    
    //    __weak typeof(self) weakSelf = self;
    
    //接触循环引用的方法1
    //__unsafe_unretained 相当于assgin关键字 修饰  当对象被回收是  对象地址不会指向nil
    //iOS 4.0推出的
    //会导致坏地址访问  俗称 野指针
    __unsafe_unretained typeof(self) weakSelf = self;
    [self.tools loadData:^(NSString *html) {
        NSLog(@"data = %@",weakSelf.view);
    }];
}

NetworkTools.h

#import <Foundation/Foundation.h>

@interface NetworkTools : NSObject


//定义网络访问方法
- (void) loadData:(void(^)(NSString *html))finished;
@end

NetworkTools.m

#import "NetworkTools.h"

@interface NetworkTools ()
@property (nonatomic,copy) void (^finishedBlock)(NSString *);

@end

@implementation NetworkTools



//block是一组准备好的代码  在需要的时候执行
//可以当做参数传递
//在异步方法中如果能直接执行block就直接执行
//如果不需要立即执行 就需要用一个属性来 记录block  在需要的时候执行

//finished执行完就解除了对self的强引用


- (void)loadData:(void (^)(NSString *))finished {
    
    //记录block
    self.finishedBlock = finished;
    //异步加载数据
    dispatch_async(dispatch_get_global_queue(0,0),^{
       
        
        //睡 3秒
        [NSThread sleepForTimeInterval:3];
        //耗时任务结束后 主线程完成回调
        dispatch_async(dispatch_get_main_queue(),^{
            NSLog(@"回调数据");
//            finished(@"终于拿到数据");
            [self working];
        });
    });
}

- (void) working {
    
    //在调用block的时候需要判断是否为空
    if (self.finishedBlock) {
        self.finishedBlock(@"回调数据");
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读