我正在试图通过Obj-C来构建iPhone游戏。
我想构建一个对象数组供以后使用。这是我试过的:
NSMutableArray *positionIcons;
[positionIcons insertObject:annotation atIndex:0];
positionIcons = [NSArray arrayWithObjects:annotation, nil];
insertObject行将计数保留为0.但是,下一行正确插入对象(并且计数移动到1)。是什么给了什么?
答案 0 :(得分:7)
您需要初始化positionIcons
,将代码更改为:
NSMutableArray *positionIcons = [[NSMutableArray alloc] init];
[positionIcons insertObject:annotation atIndex:0];
positionIcons = [NSArray arrayWithObjects:annotation, nil];
答案 1 :(得分:4)
@msaeed有正确的答案,但是值得在代码片段上花一点时间,因为它会泄漏内存。
The iPhone doesn't support garbage collection,因此了解Objective-C的半自动内存管理是如何工作的很重要。 Apple has a good reference here,但它的要点是你负责保持对象的“保留计数”。在使用-init
实例方法(例如示例中的[[NSMutableArray alloc] init]
)初始化对象时,以及使用以“init”开头的任何其他方法(如[[NSMutableArray alloc] initWithCapacity:42]
)时,新初始化的对象具有保留计数1.对该实例的-retain
方法的后续调用会增加保留计数,而对实例的-release
方法的调用会减少计数。当计数达到0时,对象将被释放,并进一步尝试发送消息将导致空指针异常。
在@ msaeed的更正代码的情况下,这是正在发生的事情,按行:
NSMutableArray
的新实例;调用-init
方法,初始化实例并将保留计数设置为1.然后将positionIcons
指针设置为此新实例的地址。-insertObject:atIndex:
上调用positionIcons
方法,并且一切都很顺利(通过约定,将对象添加到像NSMutableArray
这样的集合中会增加该对象的保留计数,这个想法是从某种意义上说,该集合现在具有该对象的“所有权”,并且不希望它从其下面取消分配。)NSArray
的新实例,然后将positionIcons
指针设置为该新实例的地址。因为{{1}的保留计数从第一行开始仍然是1,它不会被释放,并且由于你丢失了对它的引用,你永远不能在它上面调用NSMutableArray
来清除它的内存。你有泄漏。按照惯例,管理使用-release
实例方法初始化的对象与类-init
等类方法的方式不同(在第一种情况下,您必须自己释放对象,但是在第二种情况下,该对象已经发送了+arrayWithObjects:
消息,并且将在下一次通过该程序的runloop时被释放,除非您在其上调用-autorelease
。