我正在研究从Matt Galloway的Effective Objective-C书中获取的代码片段。片段如下(我已经修改了一点)。
- (void)downloadData {
NSURL *url = // alloc-init
NetworkFetcher *networkFetcher =
[[NetworkFetcher alloc] initWithURL:url];
[networkFetcher startWithCompletionHandler:^(NSData *data){
NSLog(@"Request URL %@ finished", networkFetcher.url);
_fetchedData = data;
}];
// ARC will put a release call for the networkFetcher here
}
正如作者所说,这种模式被不同的网络库使用,并且存在一个保留周期。保留周期对我来说非常明显,因为如果您从对象图的角度考虑,networkFetcher
实例通过completionHandler
属性(copy
ied )保留块,而块保留它,networkFetcher
因为它在中使用它NSLog
。
现在,要中断块,NetworkFetcher
必须将完成处理程序设置为完成nil
下载已请求的数据。
// in NetworkFetcher.m class
- (void)requestCompleted {
if(self.completionHandler) {
// invoke the block
self.completionHandler();
}
self.completionHandler = nil;
}
好的。这样就没有保留周期了。该块在运行时,它会释放其对 的引用,networkFetcher
并networkFetcher
产生nil
对块的引用。
现在,我的问题是关于片段的执行流程。以下操作顺序是否正确?
networkFetcher
运行完成处理程序- 该块被执行
- 该块释放对
networkFetcher
networkFetcher
释放对块的引用
我的怀疑取决于行动 3) 和 4) 。如果 3) 在 4) 之前执行,则没有人引用networkFetcher
,因此可以在任何执行时间释放它(ARC 将在 结束时发出释放调用downloadData
)。我错了还是我错过了什么?
希望问题很清楚。