2009-05-29 3 views
1

Я пытаюсь заполнить словарь динамически в цикле, как так:Наполнение объекта в Objective 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, не выпуская их каждый раз в цикле? Я все еще пытаюсь понять управление памятью в объективе-c.

+0

Что бы вы выпустили во время цикла? Все данные (ключи, значения и сам словарь) все еще активно используются. –

ответ

5

Это зависит от того, что myObject действительно есть и как у вас есть его свойства. Предполагая, что вы определили их для выпуска, например, здесь:

@property (nonatomic, retain) SomeClass *myProperty; 

то да, вы можете это сделать. Сетчатчики автоматически синтезируются для вас путем создания объекта-c и устанавливаются на ноль старых значений свойств перед сохранением и назначением новых значений.

Однако, хотя с вашей системой управления памятью проблем не возникает, все еще существует проблема с вашим кодом. Помните, что 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. Метод «сохранить» увеличивает счетчик ссылок, в то время как «выпуск» уменьшает его. Когда счетчик ссылок достигает 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

Ваш вопрос очень открытый, это зависит от того, как реализованы ваши Object и Dictionary.

Во-первых, вы выделяете объект только один раз и освобождаете его в цикле 10 раз -> проблема с памятью.

Если мы пройдем мимо этого. Предположим, что вы выделяете новый объект на каждой итерации цикла.

Возьмите NSMutableDictionary и MyObject, который расширяет NSObject в качестве примера вашего объекта и словаря.

Когда вы вызываете setObject: forKey на экземпляр NSMutableDictionary, объект получает вызов сохранения, поэтому словарь сохраняет ссылку на него.

Когда вы в release в конце итерации словарь по-прежнему ссылается на него, так что это нормально.

Другое дело, иметь в виду, если вы используете это в большом цикле:

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

является тот факт, что autoreleased объекты идут в autorelease бассейн. Пул очищается в конце текущей обработки событий. Если вы создаете много объектов, это может занять много времени, чтобы пройти через конец обработки событий. В этом случае вы могли бы создать свой собственный пул авторесурсов только для цикла, но я предполагаю, что это более продвинутая тема.

Определенно взгляните на некоторые ссылки Objective-c и управления памятью от Apple.

0

Что вы делаете, работает только с одним объектом и помещает этот объект в словарь десять раз. Он не помещает в словарь десять отдельных объектов.

Смежные вопросы