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

时间:2016-04-14 16:17:46

标签: objective-c macos cocoa objective-c-blocks

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

这是一般模式:

- (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时如何更改?

1 个答案:

答案 0 :(得分:1)

不确定你为什么在这里做autorelease,因为看起来普通release应该做的工作似乎只是平衡alloc

使用ARC时,没有任何东西可以保留在该控制器上,因此可以立即在此处取消分配。

你可以稍微重新调整一下,以便在实例化后传递完成,这样块实际上会捕获我认为你试图实现的实例。

您还需要添加__block存储说明符以修改块内的controllernil输出控制器,以便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();
});