2009-05-29 116 views
1

我试图填充字典动态在for循环中,像这样:目标C填充对象

伪代码

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中的内存管理。

+0

你会在循环中释放什么?所有数据(键,值和字典本身)仍处于活动状态。 – 2009-05-29 03:26:34

回答

5

这取决于myObject究竟是什么以及如何定义其属性。假设你让他们定义释放如这里:

@property (nonatomic, retain) SomeClass *myProperty; 

然后是的,你可以做到这一点。通过objective-c发布,setters会自动为您合成,并在保留和分配新值之前设置为零的旧属性值。

但是,尽管你的内存管理没有问题,但是你的代码仍然存在问题。请记住,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,所以你不会一遍又一遍地修改同一个对象。

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

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]; 

,你就不必叫“发行”插入后。

0

你的问题是非常开放的,这取决于你的ObjectDictionary是如何实现的。

首先,你只分配一次对象,并在循环中释放它10次 - >内存问题。

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

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

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

release它在迭代结束时,字典仍然保持对它的引用,所以它没问题。

另一件事要记住,如果你使用这一个大循环:

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

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

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

0

你正在做的事情只有一个对象,并将该对象放入字典十次。它不会将十个单独的对象放入字典中。