swift之block的循环引用

来源:互联网 发布:linux 装gnu gcc 编辑:程序博客网 时间:2024/06/14 09:02

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 = %@",html);        //现在会产生循环引用嘛?        NSLog(@"%@",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(@"回调数据");    }}


0 0
原创粉丝点击