我可以在具有自己的回调块的方法中释放控制器吗?

Can I dealloc a controller in a method with its own callback block?

我有一个关于使用回调块在给定堆栈帧中释放控制器的一般性问题。这目前正在按预期工作,控制器收到 dealloc 消息,没有其他明显问题。这(在我看来)对于显示瞬态弹出窗口、对话框和其他视图很有用,而无需在主机中维护 ivars 或其他状态 class。如果控制器的 xib 设置为在关闭时解除分配,这将变得非常干净。

这是一般模式:

- (void)showTransientView
{
    MyCustomController *controller = nil;

    void(^completeBlock)(ResponseCodeType) = ^(ResponseCodeType response){
        if (response == ResponseOk){
            [self transientViewDidEnd:controller];
        }

        [controller autorelease]; //project is not using ARC
    };

    controller = [[MyCustomController alloc] initWithCallback:completeBlock];
}

我的问题基本上是这里是否存在我没​​有考虑的隐藏问题或其他异议?

此外,除了明显删除 [controller autorelease] 之外,打开 ARC 时这会有什么变化?

不确定你为什么要在这里做 autorelease 因为它似乎是一个简单的 release 应该做的工作似乎因为你只是在平衡 alloc


使用 ARC 时,该控制器上没有任何内容,因此它会立即在此处释放。

您可以稍微调整一下,以便在实例化后通过完成,这样块将实际捕获实例,这就是我认为您正在尝试实现的目标。

您还需要添加 __block 存储说明符以在块内修改 controller 并在控制器外 nil 以便 ARC 发送释放

__block MyCustomController *controller = MyCustomController.new;

controller.completion = ^{
  controller = nil;
};

// Using weak in this example to ensure the dispatch_after is not the thing holding onto our controller
__weak __typeof(controller) weakController = controller;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  weakController.completion();
});