我有一个容器UIViewController
,在移除其中一个子容器时会执行以下操作:
- (void)removeChildWithIndex:(NSUInteger)Index {
@autoreleasepool {
ChildViewController *child = [_children objectAtIndex:Index];
//Remove the child from the VC hierarchy
[child willMoveToParentViewController:nil];
[child.view removeFromSuperview];
[child removeFromParentViewController];
//Remove the child from array
[_children removeObjectAtIndex:Index];
}
//Post a notification for anyone who might care
[[NSNotificationCenter defaultCenter] postNotificationName:RemovedChildNotification object:self];
}
我的问题的根源是child
在dealloc
块的末尾没有被@autoreleasepool
编辑,而是稍后被释放(从它的外观来看)在RunLoop有机会处理未完成事件的内部列表之后):
这通常不会有问题,但是观察上面函数末尾发出的NSNotification
的一个对象依赖于之前的child
dealloc
它会收到通知。
有人可以解释/链接我的一些文档,以帮助我理解为什么child
没有立即发布?
或者,如果我对child
dealloc
的编辑时间没有选择,那么在dealloc
之后,有人可以建议一种简洁的方法来延迟我的通知吗?我想我可以在[ChildViewController dealloc]
拨打一个电话通知家长其死亡并在那时发出通知,但这是一种相当肮脏的方式......
答案 0 :(得分:1)
尝试在下一个runloop迭代中发送通知:
- (void)removeChildWithIndex:(NSUInteger)Index
{
ChildViewController *child = [_children objectAtIndex:Index];
//Remove the child from the VC hierarchy
[child willMoveToParentViewController:nil];
[child.view removeFromSuperview];
[child removeFromParentViewController];
[child didMoveToParentViewController:nil];
//Remove the child from array
[_children removeObjectAtIndex:Index];
//Post a notification for anyone who might care
[self performSelector:@selector(_postRemoveChildNotification) withObject:nil afterDelay:0.0f];
}
- (void)_postRemoveChildNotification
{
[[NSNotificationCenter defaultCenter] postNotificationName:RemovedChildNotification object:self];
}
答案 1 :(得分:0)
代码中的主要问题是autoreleasepool
whcih
自动释放池块提供了一种可以放弃的机制 对象的所有权,但避免它的可能性 立即解除分配
基本上autoreleasepool
将帮助您删除autorelease块中对象的所有权,但会保证它们不会立即释放。
所以你需要做的就是删除autoreleasepool
块并让你的代码保持原样并在代码的底部你也可以让孩子成为child = nil
这也会帮助你的班级收到通知。
另外,不要编写基于以下事实的代码:在执行代码时将释放某些对象。 SO无法保证在调用方法后立即释放一个对象。这只是一种不好的做法,如果可以,你应该重新考虑你的实施。