将对象传回块中

Passing the object back in a block

有很多关于在像这样的块中访问 self 时如何避免保留循环的问题和答案...

MYObject *obj = [[MYObject alloc] init];
__weak typeof(obj) weakObj = obj;
obj.completionBlock = ^(){
    NSLog(@"my message %@", weakObj.message);
};

但是对于像 NSTask 这样的 类,终止处理程序实际上将任务对象包含在块回调中...

NSTask *task = [[NSTask alloc] init];
// Set up task...
task.terminationHandler = ^(NSTask *aTask){
    NSLog(@"Task Launch Path: %@", aTask.launchPath);
};

[task launch];

那么问题来了,这个对象是如何在内部发回给自己的? 是对自身或副本的弱引用,还是完全不同的东西?

 __weak typeof(self) weakSelf = self;
 _terminationHandler(weakSelf);

或者...

_terminationHandler([self copy]);

你唯一需要担心由块引起的保留周期是当块作为闭包时,捕获某些东西外部 到块,例如 self。但是在您给出的示例中,没有捕获块外部的任何内容:

task.terminationHandler = ^(NSTask *aTask){
    NSLog(@"Task Launch Path: %@", aTask.launchPath);
};

在块中,您指的不是 task - 您指的是 aTask。好吧,aTask 不在块外部;它是块的内部——它是传递到块中的参数。因此,没有捕获也没有保留周期:task 保留了一个 terminationHandler,这使得 没有引用 task,所以没有危险圆。这正是 为什么 任务会向您提供对自身的引用作为块的参数 - 这样您 可以 引用它。

如果您要在块中引用 task(而不是 aTask)和 运行 分析器,果然,您会收到有关危险的警告一个保留周期!