Iphone 关于在添加到数组的对象中保留对象计数的问题,Obj-C

Iphone 关于在添加到数组的对象中保留对象计数的问题,Obj-C,iphone,objective-c,memory-management,Iphone,Objective C,Memory Management,我正在开发一款iPhone应用程序,有一个关于内存管理的问题。 假设我有一个名为Company的类,它有一个NSNumber属性(非原子,retain)名为Id。 我这样做: Company *company = [[Company alloc] initWithId:[NSNumber numberWithInt:1]]; Id的保留计数现在应该为1? 那么我会: NSMutableArray *array = [[NSMutableArray alloc] init]; [array ad

我正在开发一款iPhone应用程序,有一个关于内存管理的问题。 假设我有一个名为
Company
的类,它有一个
NSNumber属性(非原子,retain)
名为
Id
。 我这样做:

Company *company = [[Company alloc] initWithId:[NSNumber numberWithInt:1]];
Id的保留计数现在应该为1? 那么我会:

NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:company];
[company release];
现在Id的保留计数是多少?还是1? 我应该在
Company
中的
dealloc
方法中添加这一点,我做
[self.Id release]
。 问题是,当我在应用程序中执行此操作并稍后尝试访问
[[array objectAtIndex:0]Id]
时,它超出了范围。在我看来,阵列保留公司,因此我应该能够“通过”阵列访问
Id
。这是正确的吗

编辑:忘了说当我从
公司
中删除
[self.Id release]
时,应用程序会工作,如果它在那里,它就会崩溃


谢谢

至于你的具体问题:是的,没错。数组保留添加到数组中的任何对象,
Company
实例应该保留
Id
对象。(旁白:属性应命名为
id
,而不是
id
,以遵循Cocoa约定。)这是假设您在
initWithId:
方法中保留值(使用
self.id
[id retain]

我看不出你的代码有什么问题。我认为错误一定是由于将
Company
对象添加到数组中,然后再次尝试访问它。您是说错误发生在添加
[self.Id release]之后行到
解除锁定
?这也会很奇怪

在我看来,要么您过度释放了
公司
对象,要么数组本身已经被释放。您是否可以尝试生成一个产生bug的小代码示例(而不是简单地说“稍后我会这样做并…”)


一个更一般的答案是,你不应该考虑确切的保留计数可能是多少。由于Cocoa的内部工作,保留计数通常会高于您预期的值。您应该跟踪的仅仅是哪些类拥有对象的所有权(例如,
NSArray
NSMutableArray
do),以及在哪些情况下您自己的代码应该/不应该拥有对象的所有权。因此,当您询问retain count是否仍然为1时,这有点离题。问题在于是否有任何对象仍然拥有所讨论对象的所有权。

首先,不要考虑以特定数字表示的保留计数。将保留视为三角洲;只能增加或减少保留计数

要回答您的具体问题:

Id上的保留计数是多少 现在?还是1?我应该在报告中补充这一点 我公司的dealloc方法 [self.Id发布]。问题是 当我在应用程序中执行此操作时,请稍后再试 要访问[[array objectAtIndex:0]Id] 这超出了范围。从我的角度来看 查看公司和公司的阵列 因此,我应该能够访问 Id“通过”数组。这是吗 对吗

Id的保留计数是一个实现细节;NSCONT缓存一个小的值子集,因此,保留计数可以是一些与您预期的任何无关的值,如果您考虑绝对值的保留计数。

如果在平衡了所有保留和释放之后尝试访问对象,则说明您没有正确遵循内存管理准则


假设您的“公司”实例保留NSNumber实例,那么,是的,它应该仍然是可行的。“超出范围”是什么意思?您是否有运行时或编译器错误?如果需要,请发布。

或者,在
initWithId:
中发布
myIdMember=[myIdArgument retain]
。感谢您的详细回答!是的,如果我从dealloc中删除[self.Id release],应用程序将按预期工作-感觉非常奇怪。我发布的代码简化了我的实际工作。然而,正如前面所说的,当我删除[self.Id release]时,一切都正常,我能得出这样的结论吗:我过度发布了Id,我根本不需要在公司类中这么做?不要修理没坏的东西,对吗?=)我不相信你可以将变量/属性命名为“id”——这是一种类型!哦我的问题更多的是原则。在我的应用程序中,它实际上被称为companyId。@chpwn事实上,你可以。但我不是说这很好。我的意思是不要把ivar资本化。关于使用id etc作为变量名的更多信息:是否设置了NSZombieEnabled标志?这通常有助于缩小过度发布的问题。我没有。它是什么?我如何使用它?