【问题标题】:nesting "alloc" with a setter in Objective-C在 Objective-C 中使用 setter 嵌套“alloc”
【发布时间】:2010-02-08 05:14:14
【问题描述】:

这里的第一个问题,这是关于 iPhoneOS3 而不是 MacOSX。我对 Objective-C 还很陌生,而且我从来没有在没有自动垃圾收集的环境中开发过,所以我对此有点困惑。以下是 Apple.com 上的示例中将视图控制器分配给应用程序委托的一些有效代码:

MyViewController *aViewController = [[MyViewController alloc]
    initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]];
[self setMyViewController:aViewController];
[aViewController release];

所以,据我了解,我必须释放 aViewController 因为它是首先分配的(+1 = 1);然后保留在 setter 中(+1 = 2);然后在 setter 中释放(-1 = 1);然后不再需要,所以最终再次释放(-1 = 0)并释放内存。我可以不只是跳过分配临时对象 aViewController 并像这样嵌套这些函数:

[self setMyViewController:[[MyViewController alloc]
    initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]]];

我想知道这是否可以正常工作?我有点担心,因为 setter 需要一个指向 ViewController 的指针,而不仅仅是一个副本。而且由于我只传递一个返回值,setter 中的指向 ViewController 的指针是否会指向可能在分配之前可能被擦除或丢失的数据?如果这似乎是一个愚蠢的问题,我很抱歉,但我很难在任何地方找到答案,我正在努力为非垃圾收集环境建立良好的技术。谢谢!

【问题讨论】:

  • 您应该按照 bbum 的建议发布您对 setMyViewController: 的实现。您的描述“然后保留在设置器中(+1 = 2);然后在设置器中释放(-1 = 1);”听起来很可疑......
  • setter 看起来像这样:@property (nonatomic, retain) MyViewController *myViewController;
  • 如果我错了,请纠正我,但我很确定会生成如下代码: - (void) setMyViewController: (MyViewController*)controller { myViewController = [controller retain]; [控制器释放]; }

标签: objective-c iphone memory-management


【解决方案1】:

不要从绝对保留计数的角度来考虑内存管理。完全从所有权和封装的角度来考虑它。

当您alloc 一个对象时,您已经创建了一个您拥有的对象。当您将该对象设置为另一个对象的值时,该其他对象应该保留该对象以表示所有权。如果您的代码不再对该对象感兴趣,那么您应该release(如果您想将其返回给其他对象,则应使用autorelease)。

[self setMyViewController:[[MyViewController alloc]
    initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]]];

为了回答您的具体问题,上述代码行本身会导致内存泄漏假设-setMyViewController: 已正确实现

【讨论】:

  • Peter Hosey 写了一篇关于对象所有权的文章:boredzo.org/cocoa-touch-intro
  • 好吧-setMyViewController 是使用保留然后释放来实现的,所以它们相互抵消对吗?而且由于我从未明确为这些数据分配任何内存,我认为它可能不需要释放。那么我该如何解决这个问题呢?
  • 为什么-setViewController:会保留,然后释放,传入的视图控制器?发布代码,因为这听起来很明显属于“未正确实施”类别。 :)
【解决方案2】:

我已经确定这段代码可以正常工作并且不会导致内存泄漏:

MyViewController *aViewController = [[[MyViewController alloc]
    initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]] autorelease];
[setMyViewController:aViewController];

感谢大家的帮助!

【讨论】:

    【解决方案3】:
    [self setMyViewController:[[MyViewController alloc]
        initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]]];
    

    在这里你分配,然后它被保留,所以你的保留计数立即为 2。但它会被正确设置,因为你仍然将 setter 指针传递给视图控制器。

    如果属性 MyViewController 的类型为分配(不是保留),则保留计数仅为 1。

    【讨论】:

    • 考虑保留计数的方式完全错误;永远不要将它们视为绝对数量。如果您导致某些东西被保留,您应该在您不再拥有所有权时导致它被释放(或自动释放)。不多也不少。
    • (我实际上并没有编辑您的评论 - 只是做了足够的空格更改以删除我不应有的反对票。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-20
    • 1970-01-01
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多