【问题标题】:Is it okay for multiple objects to retain the same object in Objective-C/Cocoa?多个对象可以在 Objective-C/Cocoa 中保留同一个对象吗?
【发布时间】:2011-02-12 12:24:54
【问题描述】:

假设我有一个列出 100 个 Foo 对象的 tableview 类。它有:

@property (nonatomic, 保留) NSMutableArray* fooList;

然后我用 Foos 填充它:

self.fooList = [NSMutableArray 数组]; 而(某事){ Foo* foo = [[Foo alloc] init]; [fooList addObject:foo]; [foo 释放]; }

第一个问题:因为NSMutableArray被标记为retain,是不是里面的所有对象也都被retain了?我是否正确添加了 foo 并在将其添加到数组后释放了本地副本?还是我错过了保留电话?

然后,如果用户选择表中的一个特定行并且我想显示我调用的详细 Foo 视图:

FooView* localView = [[FooView alloc] initWithFoo:[self.fooList objectAtIndex:indexPath.row]]; [self.navigationController pushViewController:localView Animation:YES]; [本地视图发布];

现在 FooView 类有:

@property (nonatomic, 保留) Foo* theFoo;

所以现在数组都保留了 Foo 以及 FooView。但这似乎没问题吧?当用户点击后退按钮时,将在 FooView 上调用 dealloc 并调用 [theFoo release]。然后按下另一个后退按钮并在 tableview 类上调用 dealloc 并调用 [fooList release]。

你可能会争辩说 FooView 类应该有:

@property (nonatomic, assign) Foo* theFoo;

对比保持。但有时 FooView 类是用不在数组中的 Foo 调用的。所以我想确保让两个对象保持在同一个对象上是可以的。

【问题讨论】:

    标签: iphone objective-c cocoa


    【解决方案1】:

    是的,没关系。这就是引用计数内存管理系统的全部意义所在。

    【讨论】:

      【解决方案2】:

      要回答您的主要问题,是的,您可以保留一个实例的多个对象。这正是引用计数内存管理的重点。查看 Cocoa Memory Management Programming Guide 了解更多信息。然后再读一遍。它有所有的答案,将成为你最好的朋友。

      基本上,发送-retain 消息表明发送方“拥有”接收方,因为在所有 所有者释放其所有权之前不应解除分配接收方。因此,单个实例不需要知道(也不应该关心)其他所有者是否存在。保留您需要保留的任何东西,并在完成后释放它。当所有所有者释放他们的所有权时,可以释放实例。

      顺便说一句,

      @property (retain,readwrite) NSMutableArray *myArray;
      

      声明声明此属性的类将保留NSMutableArray 实例。 NSArrayNSDictionaryNSSet(及其可变子类)始终保留其内容。

      【讨论】:

        【解决方案3】:

        正如其他人所说,您所做的是正确的,并且代码在我看来是正确的。我的代码中有数十个对同一个对象的引用,只要我平衡了所有的保留和释放,一切正常。

        要添加更多细节......你问:

        因为NSMutableArray被标记为retain,也就是说里面的所有对象也都被retain了?

        这是两个不同的东西。所有集合类(字典、数组、集合)都会自动保留您添加到它们的内容,并在释放集合对象时释放它们的内容对象。 (在 NSMutableArray 的情况下,如果您从数组中单独删除内容对象,或者当您释放整个数组时,内容对象将被释放。)

        这与集合对象本身是保留还是分配为属性无关。唯一需要考虑的是,如果您对集合对象属性的策略不正确,它可能会比您想象的迟早发布,并且事情可能会失去平衡。

        正如其他人所说...阅读memory management guide,然后练习。 :) 哦,从这个角度也阅读其他人的代码,并尝试了解他们如何/为什么进行内存管理。

        另外一件小事...对于每个保留的属性,请确保您在对象的 dealloc 方法中有一个释放调用。

        【讨论】:

        • 错字:“......并在释放集合对象时释放其内容对象。”集合中的对象在集合释放之前不会被释放。
        • 谢谢,已修复。尽管您可能会争辩说,“已发布”我的意思是“最后一个版本,其中保留计数变为零,这会触发 dealloc”:P 但只是说 dealloc 在这种情况下更清楚。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-05
        • 2011-03-20
        • 2022-11-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多