从Apple的PageControl卸载ViewControllers示例+ UINavigationController与其RootViewControllers的关系

时间:2009-08-28 17:15:49

标签: iphone objective-c cocoa-touch

因此,我修改了Apple的PageControl示例,以便将各种导航控制器(以及它们的根视图控制器)动态加载到滚动视图中。我还添加了一种技术,试图在不再需要时卸载导航控制器。我只在ObjC呆了一个多月,所以我不确定我是否正确卸货。请参阅下面的代码,然后是我的问题。


首先,我创建一个可变数组并用空值填充它,就像Apple一样:

// Create dummy array for viewControllers array, fill it with nulls, and assign to viewControllers
NSMutableArray *array = [[NSMutableArray alloc] init];
for (unsigned i = 0; i <= kNumberOfPages; i++)
{
    [array addObject:[NSNull null]];
}

self.viewControllers = array;
[array release];

...稍后,我用UINavigationController对象填充数组(这只是部分代码,请原谅丢失的部分......主要的想法是我分配了一些东西,分配它们和然后发布):

id controller = [[classForViewController alloc] initWithNibName:NSStringFromClass(classForViewController) bundle:nil];
    navController = [[UINavigationController alloc] initWithRootViewController:controller];
    [controller release];
    [self.viewControllers replaceObjectAtIndex:page withObject:navController];
    [navController release];

...最后,如果不再需要加载页面,我会这样做:

[self.viewControllers replaceObjectAtIndex:i withObject:[NSNull null]];

问题:

  1. 我的理解是,一旦我将viewControllers数组中的导航控制器替换为null,该阵列就会释放导航控制器。因此,导航控制器的保留计数达到零并且不再占用内存。这是对的吗?

  2. 导航控制器内的根视图控制器怎么样?我是否需要对其执行任何操作,或者在导航控制器的保留计数达到零后自动释放?

  3. 谢谢!

2 个答案:

答案 0 :(得分:1)

  1. 是。放入集合的任何对象都会发送retain消息。同样,从集合中删除的任何对象都会发送release消息,删除的原因无关紧要。
  2. 是的,所有对象都会在释放后释放它拥有的所有对象。
  3. 这一切都归结为Cocoa定义的简单所有权原则:

    • 如果您通过调用以下方法将其作为返回值接收,则您拥有该对象:
      1. 名为allocnew
      2. 包含 copy 一词,例如copymutableCopy
    • 如果您致电retain,则拥有该对象。
    • 您只能在自己拥有的对象上拨打releaseautorelease
    • 必须dealloc方法释放所有拥有的对象。

    只有一个例外;代表从未拥有。这是为了避免循环引用和它们导致的内存泄漏。

    作为副作用,这也意味着当您自己实现方法时,必须返回自动释放的对象,除非您实现new或使用的方法复制的名字。作为out参数返回的对象总是自动释放。

    严格遵守此规定,可以将Objective-C视为95%的垃圾收集。

答案 1 :(得分:0)

大概是的,一旦你的保留计数达到零(无论何时发生),你的对象都会收到dealloc消息。您可以设置断点以确保发生这种情况。仪器带有泄漏实用程序,可以帮助您找到内存问题,这是一个很好的工具,我建议经常使用它。

我不太确定你对“做任何事情”的意思。我认为你的意思是释放它。一般模式是,如果您allocretain,则为release。如果您的分配和保留数量超过您的版本,您可以大致猜测是否会出现问题(反之亦然,您不希望双重释放)。