4

我是一名经验丰富的 C/C++ 程序员,开始学习 Objective-C 开发。我目前正在查看 UICatalog 示例,并遇到了另一个我见过几个地方但从未理解过的成语实例。

代码:

ButtonsViewController *buttonsViewController = [[ButtonsViewController alloc] initWithNibName:@"ButtonsViewController" bundle:nil];
[self.menuList addObject:[NSDictionary dictionaryWithObjectsAndKeys:
                                       NSLocalizedString(@"ButtonsTitle", @""), kTitleKey,
                                       NSLocalizedString(@"ButtonsExplain", @""), kExplainKey, 
                                       buttonsViewController, kViewControllerKey, nil]];
[buttonsViewController release];

AFAIK,这分配并初始化一个 ButtonsViewController,为 ButtonsViewController 创建一个 NSDictionary,并将字典添加到一个名为 menuList 的 NSMutableArray(这是上面代码所在的 MainViewController 的成员变量),然后释放它刚刚创建的 buttonViewController。稍后,MainViewController 在必要时使用字典条目将视图切换到buttonsViewController。

我的问题是:为什么buttonViewController 在这段代码之后仍然有效?它被分配和释放,之间没有“保留”。向 NSDictionary 或 NSMutableArray 添加内容是否具有隐式“保留”?如果是这样,我应该能够以某种方式弄清楚这一点,还是只是你必须阅读和记住的那些事情之一?

4

4 回答 4

4

这是 Cocoa 框架中的标准过程,用于集合保留它们包含的对象。所以是的,可变数组保留了视图控制器。

除非文档另有说明,否则情况总是如此。

于 2011-01-19T02:15:15.633 回答
4

因此,虽然该对象在之后确实有效,因为集合保留了它,但我不确定以这种方式考虑它是否有用。如果您打算在将对象添加到集合后在该方法中使用该对象,则在完成之前不应释放它。

思考它的方法是这样的:

1) 我拥有我创建的这个对象的所有权

2) 现在集合和我都拥有这个对象的所有权

3)现在只是集合,我不应该使用该对象,因为我没有它的所有权

并忽略这样一个事实,即在这种情况下,您可以在技术上摆脱不注意 3 的情况。

这允许您继续使用 NARC(new-alloc-retain-copy)规则来考虑保留对象的内容。

于 2011-01-19T04:46:58.597 回答
3

如前所述,NSDictionary 和 NSArray 向添加的对象发送保留消息,并在删除时向对象发送释放。上面的代码在概念上将buttonsViewController 的所有权转移到字典。您可能如何知道这一点的一个示例......来自文档:

-addObject:forKey:

参数: anObject - 键的值。该对象在添加到字典之前会收到一条保留消息。该值不能为零。

-removeAllObjects

讨论:每个键和对应的值对象都被发送一个释放消息。

于 2011-01-19T02:24:57.587 回答
1

是的,像 NSDictionary 和 NSMutableArray 这样的容器会保留(或在字典键的情况下复制)您放入其中的对象。

请参阅 Apple 的Collections Programming Topics指南。

于 2011-01-19T02:11:37.987 回答