2010-03-12 2 views
14

Мне было интересно, нужно ли мне выпустить скопированный NSObject? Например, я создаю только один словарь, который я скопировать в массив:Должен ли я освободить скопированные NSObjects - Objective-c

Код:

for (int num = 0; num < [object count]; num++) { 
    [dictionary setObject:[object objectAtIndex:num] forKey:@"x"]; 
    [array addObject:[dictionary copy]]; 
} 

ли я выпустить словарь? Если да, то когда?

Thanks

+0

+1 хороший вопрос – andy

+3

Как эмпирическое правило, в Cocoa вам нужно освободить все, что у вас есть. У вас есть что-то, если вы послали его с новыми, скопировали, выделили или сохранили. Если вы не назвали один из этих методов, вы его не обладаете, и вы не должны его выпускать. –

ответ

24

Да, это так. В этом случае, вероятно, вы должны освободить копию сразу после добавления его в массив, поскольку массив сохраняет что-либо добавил к нему:

NSDictionary *copied = [dictionary copy]; 
[array addObject:copied]; 
[copied release]; 
+0

Спасибо за информацию! – ncohen

4

Этот фрагмент из документации:

- (ID) копия

Возвращаемое значение Объект, возвращаемый методом протокола NSCopying copyWithZone :, где зона равна нулю.

Обсуждение Это удобный метод для классов, которые принимают протокол NSCopying. Исключение возникает, если для copyWithZone нет реализации.

NSObject сам по себе не поддерживает протокол NSCopying. Подклассы должны поддерживать протокол и реализовывать метод copyWithZone :. Подклассовая версия метода copyWithZone: должна сначала отправить сообщение super, чтобы включить его реализацию, если только подкласс не сходит непосредственно из NSObject.

Особые соображения Если вы используете управляемую память (а не сбор мусора), этот метод сохраняет новый объект перед его возвратом. Однако вызывающий метод отвечает за освобождение возвращаемого объекта.

2

С copy вы берете на себя ответственность за возвращенный объект. Контейнеры также берут на себя ответственность за объекты, добавленные к ним.
В результате вы должны отказаться от права собственности на копию, как указал Ной. Cocoa memory management guidelines содержит раздел, обозначающий how to work with containers.

0

Сложно сказать, не видя, где вы создаете словарь, насколько это разумно в любом случае. Если нет других членов в словаре, было бы проще (хотя, возможно, труднее читать :) сделать что-то вроде

for (int num = 0; num < [object count]; num++) { 
    [array addObject:[NSDictionary 
          dictionaryWithObject:[object objectAtIndex:num] 
             forKey:@"x" 
        ] 
    ] 
} 

То собирается дать вам реальные NSDictionary объекты в массиве, а не NSMutableDictionary копии, которые вы создаете.

+0

На каком основании вы утверждаете, что копия NSMutableDictionary не будет «* реальным NSDictionary»? –

+0

Исходя из того, что * real * NSDictionary будет вызывать ошибки, если вы попытаетесь вставить в него объекты. – Jeff

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