美文网首页
block 循环引用

block 循环引用

作者: foolish_hungry | 来源:发表于2018-06-23 18:36 被阅读0次

在使用块时, 如果不仔细思考, 很容易出现"保留环" (retain cycle). 下面举个例子:

我们创建一个获取网络数据的类

TYLNetworkFetcher.h

#import <Foundation/Foundation.h>

typedef  void (^TYLNetworkFetcherCompletionHandler) (NSData *data);

@interface TYLNetworkFetcher : NSObject

- (void)startWithCompletionHandler:(TYLNetworkFetcherCompletionHandler)completion;

@end

TYLNetworkFetcher.m


#import "TYLNetworkFetcher.h"

@interface TYLNetworkFetcher ()

@property (nonatomic, copy) TYLNetworkFetcherCompletionHandler completionHandler;
@property (nonatomic, copy) NSData *downloadData;

@end

@implementation TYLNetworkFetcher

- (void)startWithCompletionHandler:(TYLNetworkFetcherCompletionHandler)completion {
    self.completionHandler = completion;
    // start request
    // set download data
    // call request completed
}

- (void)p_requestCompleted {
    if (_completionHandler) {
        _completionHandler(_downloadData);
    }
}

@end

我们在ViewController.m中使用它:


#import "ViewController.h"
#import "TYLNetworkFetcher.h"

@interface ViewController ()

@property (nonatomic, strong) TYLNetworkFetcher *networkFetcher;
@property (nonatomic, copy) NSData *fetchData;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    _networkFetcher = [TYLNetworkFetcher new];
    [_networkFetcher startWithCompletionHandler:^(NSData *data) {
        _fetchData = data;
    }];
}

接下来我们编译的时候, xcode 并没有提示我们会造成循环引用

我们分析一下引用关系 如下图:

image.png

我们可以有如下三种方式去解决循环引用问题:

  1. _networkFetcher 实例变量不再被ViewController 持有
image.png
  1. 使得 _networkFetcher的属性 不再持有completionHandler
image.png
  1. 修改 将viewController 对 networkFetcher属性的引用, 改为weak
image.png

推荐使用第2种方式

参考 (编写高质量iOS 与 OX 52 个有效方法)

相关文章

网友评论

      本文标题:block 循环引用

      本文链接:https://www.haomeiwen.com/subject/zokdyftx.html