块中self的引用计数问题

3
我正在尝试理解对象生命周期和引用计数如何与代码块交互。在下面的代码中,我只是做了一个简单的动画,在 UINavigationController 的堆栈中交换顶部视图时会闪烁。棘手的部分是 弹出的视图控制器是定义此代码的视图控制器
[UIView animateWithDuration:0.2 
        animations:^{self.navigationController.view.alpha = 0.0;}
        completion:^(BOOL finished){ 
                UINavigationController *navController = self.navigationController;  

                [self.navigationController popViewControllerAnimated:NO]; 
                [navController pushViewController:nextView animated:NO];
                [nextView release];

                [UIView animateWithDuration:0.2 
                        animations:^{navController.view.alpha = 1.0;}];                    
                 }];    

我的问题是(不考虑动画效果),从内存管理的角度来看,这种方法是否正确。特别是:
(1)当使用此方法进行“弹出+推入”循环时,是否不再需要保留self,就像其他相似例子中不使用块一样?
(2)在使用这些块调用animateWithDuration:...时,是否会保留定义的视图控制器(self)直到块执行?
1个回答

5
(1) 当使用这种pop+push循环的方法时,不再需要像其他类似示例那样保留self,如果nextView是局部变量,则这些块会自动保留self、navController和nextView。
(2) 使用animateWithDuration:...调用这些块会使定义的视图控制器(self)一直保留到块执行吗?这些块通过该方法从堆栈复制到堆中。这些块在执行后被释放。然后self、navController和nextView从这些块中释放。

所以,'self'和navController被保留,因为它们在块内部被积极引用,对吗?但是,如果上面的代码没有"navController = self.navigationController"这一行,而是有"navController = mNavigationController" - 其中mNavigationController是一个实例变量,那么mNavigationController将被保留,但不会保留'self'。对吗?我只想确认块是否自动保留它们的“主机”实例,即“self”。 - Dev Kanchen
1
"self.navigationController" 和 "[self navigationController]" 是等价的,而 "mNavigationController" 和 "self->mNavigationController" 也是等价的,因此在这两种情况下都会保留 self。如果您想避免保留 self,请使用本地变量,如 "UINavigationController *controller = self.navigationController;",然后在块中使用 "controller"。 - Kazuki Sakamoto
评论已删除:我现在明白了!谢谢。 - Dev Kanchen
我执行了 ATSDragToReorderTableViewController *blockSelf = self; 并使用了本地的 blockSelf,但是一些方式下 self 仍然被保留并且没有释放(当我弹出它时 dealloc 方法没有被调用)。我做错了什么??? - Hlung
嗯,我建议您创建一个带有代码片段的问题。 - Kazuki Sakamoto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接