在Objective C中填充对象

时间:2009-05-29 03:21:22

标签: objective-c cocoa

我正试图在for循环中动态填充字典,如下所示:

伪代码

myObject = new Object
myDict = new Dictionary
for(int i; i < 10;i++)
  myObject.value1 = new data from somewhere
  myObject.value2 = new data from somewhere
  myDic = value:myObject key:i
end for

所以我的问题是在objective-c中,我可以继续将新数据分配给myObject而不是每次都在循环中释放它吗?我仍然试图在objective-c中找出内存管理。

4 个答案:

答案 0 :(得分:5)

这取决于myObject实际是什么以及如何定义其属性。假设你已将它们定义为发布,例如:

@property (nonatomic, retain) SomeClass *myProperty;

然后是的,你可以这样做。 setter通过objective-c release自动合成,并在保留和赋值之前设置为nil旧属性值。

但是,虽然您的内存管理没有问题,但代码仍然存在问题。请记住,myObject是一个指针,就像在C或C ++中一样。这意味着如果将其添加到myDic然后稍后修改对象的属性(例如在for循环的下一次迭代中),那么当您将对象从字典中拉出时,将反映这些更改未来的某些方面。你想要的是这样的:

myObject = nil
myDict = new Dictionary
for(int i; i < 10;i++)
  myObject = new Object
  myObject.value1 = new data from somewhere
  myObject.value2 = new data from somewhere
  myDic setValue:myObject forKey:i
  myObject release
end for

这样做是在将myObject放入字典之后释放Object(所有可可集合类都会保留您放入其中的任何对象,并在删除它们或释放集合本身时释放它们)所以你不要没有泄漏,并且在每次迭代时都会分配{{1}}的新实例,因此您不会反复修改同一个对象。

如果您还没有阅读Apple Memory Management Guide for Cocoa,我强烈建议您这样做。这是非常有益的。

答案 1 :(得分:0)

Objective-C中的内存管理是通过引用计数完成的。分配对象时,它的引用计数为1.“retain”方法会增加引用计数,而“release”会减少引用计数。当引用计数达到0时,调用'dealloc'方法(你永远不应该明确地调用'dealloc')并释放对象。

你也可以在一个对象上调用'autorelease',这会在一段时间后减少引用次数。这允许您使用该对象而不必担心释放它。

对于你的问题。将对象添加到容器时,会对插入的对象进行“保留”调用。这意味着您必须“释放”插入的对象:

NSMutableDictionary *myDict = [[NSMutableDictionary alloc] init];
for( int i = 0; i < 10; ++i ) {
    Object *myObject = [[Object alloc] init];
    [myDict setObject:myObject forKey:[NSNumber numberWithInt:i]];
    [myObject release];
}

你也可以使用:

Object *myObject = [[[Object alloc] init] autorelease];

并且您不必在插入后调用'release'。

答案 2 :(得分:0)

您的问题非常开放,具体取决于ObjectDictionary的实施方式。

首先,您只分配一次对象并在循环中释放它10次 - &gt;记忆问题。

如果我们过去了。假设您在循环的每次迭代中分配新对象。

将NSMutableDictionary和扩展NSObject的MyObject作为对象和词典的示例。

当您在NSMutableDictionary实例上调用setObject:forKey时,该对象将接收保留调用,因此字典会保留对它的引用。

当你在迭代结束时release时,字典仍然会引用它,所以它没问题。

如果你在一个大循环中使用它,请记住另一件事:

Object *myObject = [[[Object alloc] init] autorelease];

是自动释放的对象进入自动释放池的事实。池在当前事件处理结束时被清理。如果您创建了大量对象,则在事件处理结束时可能需要花费大量时间来完成它。在这种情况下,您可能会选择仅为循环创建自己的自动释放池 - 但我想这是更高级的主题。

绝对看看Apple的一些Objective-c和内存管理参考。

答案 3 :(得分:0)

您所做的只与一个对象一起工作,并将该一个对象放入字典十次。它没有将十个单独的对象放入字典中。