Вопрос о сохранении и копировании в Задаче c - PullRequest
0 голосов
/ 11 января 2011

Этот вопрос меня немного смутил.В файле ".h".

@property (nonatomic,retain) NSMutableString *str1;
@property (nonatomic,copy) NSMutableString *str2;

В файле ".m".

NSMutableString *testRetain = [[NSMutableString alloc] initWithString:@"prefix"];
 NSLog(@"retain count is %d",[testRetain retainCount]);
 NSLog(@"mem add is %p",testRetain);

 str1 = testRetain;
 NSLog(@"retain count is %d",[testRetain retainCount]); 
 NSLog(@"mem add is %p",testRetain);

 str2 = testRetain;
 NSLog(@"retain count is %d",[str2 retainCount]); 
 NSLog(@"mem add is %p",str2);

все адреса retainCount и памяти совпадают.Как я знаю, @property (nonatomic, retain) добавит retainCount объекта, на который будет указывать. Во второй части кода должен выводиться один и тот же адрес памяти и другое содержимоеCount из первой части кода.@property (nonatomic, copy) скопирует объект в новую область. Поэтому третья часть кода должна выводить другой адрес памяти из первой части кода.Почему я получил этот результат.Большое спасибо.

Ответы [ 4 ]

4 голосов
/ 11 января 2011

Два очка. Первое и самое важное: не используйте retainCount в качестве инструмента отладки. Есть много причин, почему это может не дать вам ожидаемой стоимости. Это говорит так же в документации.

Но в этом случае - пункт два - причина, по которой он не работает, заключается в том, что вы обращаетесь к переменным напрямую, а не используете средства доступа.

Вместо:

str = testRetain;

Попробуйте:

self.str = testRetain;
3 голосов
/ 11 января 2011

То, что вы должны использовать, это на самом деле такой код:

self.str1 = ...;

Только так будет вызываться метод установки.

Кодируя так:

str1 = ...;

Вы фактически обращаетесь к переменной экземпляра напрямую, не вызывая метод setter, поэтому сохранение / копирование не произошло.

3 голосов
/ 11 января 2011

Используя "str1" вместо "self.str1", вы не будете использовать свои (предположительно синтезированные) методы доступа для свойства, поэтому управление памятью, которое они осуществляют, не происходит.

Какдополнительное примечание: вы должны быть очень осторожны при использовании метода -retainCount.Cocoa Touch часто делает очень странные вещи с счетом сохранения (сохранение, освобождение и автоматическое высвобождение внутри себя, хранение «специальных» счетчиков хранения для постоянных объектов и т. Д.), Которые затрудняют эффективное использование.

Вместо того, чтобы использовать счет сохранения, я предлагаю подумать об увеличении счетчика хранения (путем -copy, -alloc, -retain, + new или -mutableCopy) в качестве «утверждения права собственности на объект» и уменьшения его(путем -release или -autorelease) как «отказ от владения объектом».Поэтому, если вы всегда владеете каждым объектом, который используете, и отказываетесь от них, когда закончите с ними, вы должны избегать как утечек, так и сбоев.

1 голос
/ 11 января 2011

str1 = testRetain; устанавливает ivar напрямую на тот же адрес памяти.Для использования аксессуаров необходимо использовать

self.str1 = testRetain;
self.str2 = testRetain;
...