我有一个关于使用回调块在给定堆栈帧中释放控制器的一般问题。这当前正在按预期工作,控制器收到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]
答案 0 :(得分:1)
不确定你为什么在这里做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();
});