如果我有一个UIViewControllers的NSArray并将释放发送到数组,是否会为每个UIViewControllers调用viewDidUnload或dealloc?或两者都没有?
这就是我正在做的事情:
- (void) viewDidLoad {
UIViewController* profileController = [[ProfileController alloc] init];
..........
//all the other controllers get allocated same way
self.viewControllers = [[NSMutableArray alloc] initWithObjects: profileController, dietController, exerciseController, progressController, friendsController, nil];
[profileController release];
//other controllers get released same way ....
}
- (void) dealloc {
[viewControllers release];
NSLog("DEALLOC!");
//I know dealloc is being called
//what happens to the view controllers?
}
我在每个视图控制器的viewDidUnload和dealloc方法中放置了一个断点,并且它们不会被调用。
答案 0 :(得分:1)
正如pgb所提到的,你混淆了内存管理和视图控制器生命周期这两个概念。每当卸载视图控制器视图时,都会调用viewDidUnload
,这当然只有在加载视图时才会发生。如果没有显示任何视图控制器,您根本不应该看到viewDidUnload
被调用。
你应该期待看到dealloc
被召唤!
您的问题在于viewControllers
数组的初始化:
self.viewControllers = [[NSMutableArray alloc]
initWithObjects: profileController,
dietController,
exerciseController,
progressController,
friendsController,
nil];
假设viewControllers
是使用retain属性的属性,这将泄漏数组,从而泄漏所有数组的内容。问题是你已经分配了一个可变数组(因此保留count = 1),然后你将它分配给viewControllers属性,这将增加保留计数。
在你的dealloc方法中,你(正确地)释放了数组,但这只会将保留计数减少到一个。
我建议的解决方法是将autorelease
添加到上面的代码中:
self.viewControllers = [[[NSMutableArray alloc]
initWithObjects: profileController,
dietController,
exerciseController,
progressController,
friendsController,
nil] autorelease];
进行此更改后,您应该会在视图控制器上看到dealloc
被调用。您还应该看到viewDidUnload
被调用,因为这些视图控制器的视图被卸载(例如,它们在基于导航控制器的应用程序中从堆栈中弹出)。
答案 1 :(得分:0)
我在这里看到两个问题,每个问题都有一个问题:
如果未加载与viewDidUnload
关联的view
,则不会调用{p> UIViewController
。您基本上混合了两个概念:内存管理(和对象生命周期)与视图控制器生命周期。虽然你可以看到两者之间存在一些并行性,但它们并不一定相关。
您是否在任何时候推动viewController
以使其视图可见?如果不是,则肯定不会调用viewDidUnload
(不会viewDidLoad
)。
对于dealloc
,如果在释放对象后没有调用它(并且你认为该对象应该从内存中dealloc
),那是因为你有内存泄漏。在您的代码中,我可以很容易地看到初始化代码中的内存泄漏:
UIViewController* profileController = [[ProfileController alloc] init];
..........
//all the other controllers get allocated same way
self.viewControllers = [[NSMutableArray alloc]
initWithObjects: profileController,
dietController,
exerciseController,
progressController,
friendsController,
nil];
当你profileController
时, retainCount
会在第一行遇到alloc
。稍后,当您将其添加到NSMutableArray
时,数组会retain
,再次突然显示retainCount
。要平衡这一点,您需要release
两次,但在release
方法上只需dealloc
一次UIViewController* profileController = [[[ProfileController alloc] init] autorelease];
..........
//all the other controllers get allocated same way
self.viewControllers = [[NSMutableArray alloc]
initWithObjects: profileController,
dietController,
exerciseController,
progressController,
friendsController,
nil];
。要解决此问题,我会将初始化更改为:
release
将添加您缺少的额外retain
并平衡视图控制器上的release
{{1}}次调用。
答案 2 :(得分:0)
当您释放数组时,它不会释放它,如果没有其他保留,则允许它被释放。
类似地,如果数组被释放,则释放内部的每个元素,但是对象可能会保留在其他位置,因此不能保证立即解除分配。
一般情况下,UI逻辑在主动呈现时会保留像视图或视图控制器这样的对象,因此直接或通过数组释放它上面的保留不会导致它被解除分配(如果它正在被释放)显示(或者,例如,在导航控制器的堆栈中)。