我可以在具有自己的回调块的方法中释放控制器吗?
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();
});
我有一个关于使用回调块在给定堆栈帧中释放控制器的一般性问题。这目前正在按预期工作,控制器收到 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();
});