Заполнение объекта в Objective-C - PullRequest
1 голос
/ 29 мая 2009

Я пытаюсь динамически заполнить словарь в цикле 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 ]

5 голосов
/ 29 мая 2009

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

@property (nonatomic, retain) SomeClass *myProperty;

тогда да, вы можете сделать это. Сеттеры автоматически синтезируют для вас релизы target-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 , я настоятельно рекомендую это сделать. Это очень информативно.

0 голосов
/ 29 мая 2009

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

0 голосов
/ 29 мая 2009

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

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

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

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

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

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

Еще одна вещь, о которой следует помнить, если вы используете это в большом цикле:

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

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

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

0 голосов
/ 29 мая 2009

Управление памятью в 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' после вставки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...