Присвоение имущества и распределение приводит к сохранению счета 2 - PullRequest
0 голосов
/ 07 сентября 2010

Я посмотрел на инструменты и увидел, что выделение увеличило счет удержания на 1. Пока все ясно. Но присвоение класса моей собственности также увеличило количество сохраняемых до 2.

self.myProperty = [[MyClass alloc] init]

Vs.

MyClass *myCreatedVariable = [[MyClass alloc] init];
self.myProperty = myCreatedVariable

Чтобы уменьшить количество сохраненных записей до нуля, я выпустил myCreatedVariable сразу после моих вызовов. Переменная экземпляра myProperty высвобождается в методе dealloc. Прав ли я, что в методе dealloc высвобождается только свойство?

Теперь на мой вопрос:

Всегда ли выделение и присвоение свойству создают счет сохранения 2? Так что не используйте

self.myProperty = [[MyClass alloc] init]

потому что счетчик никогда не получает ноль? Или это только тот случай, если я выделяю класс?

Приветствия

Ответы [ 4 ]

4 голосов
/ 07 сентября 2010

Ваша собственность, скорее всего, объявлена ​​как сохраняющая или копирующая:

@property (retain) MyClass myProperty;

или

@property (copy) MyClass myProperty;

Это вызывает ваш установщик, который делает то, что его атрибуты говорят: сохраняйте!Копия также сохранится.

Хотя это сработало здесь, вам не следует пытаться получить полезную информацию из свойства retainCount.

Я не могу рекомендовать Руководство по программированию управления памятью достаточно высоко, стоит первого, второго и третьего чтения.: -)

1 голос
/ 20 января 2011
@property (nonatomic, retain) NSString *strURL;

Это сохранит счет сохранения = 0

Когда вы используете аксессор для инициализации strURL, то количество сохранений увеличивается до 1

self.strURL = [NSString stringWithString:@"http://192.168.1.25/shop.php"];

Однако, если бы вы сделали это без использования средства доступа, то ваш счетчик ссылок остался бы таким же, как 0

strURL = [NSString stringWithString:@"http://192.168.1.25/shop.php"];

Обратите внимание, что при использовании этой переменной с счетом сохранения равным 0, автоматическое освобождение срабатывает и переменная освобождается, выдавая ошибку «SIGABART» или «EXC_BAD_ACCESS» при попытке доступа к ее значению.

Обычно, когда вы используете init для инициализации переменных, лучше всего использовать alloc.

strURL = [[NSString alloc] stringWithString:@"http://192.168.1.25/shop.php"];

Надеюсь, это поможет!

1 голос
/ 07 сентября 2010

Создание объектов с использованием функции init возвращает по умолчанию сохраненный экземпляр. (См. Руководство по программированию для управления памятью)

Если свойство определено с атрибутом 'retain', то вашобъект сохраняется еще раз.

Итак, правильный способ сделать это -

MyClass *myCreatedVariable = [[MyClass alloc] init];
self.myProperty = myCreatedVariable;
[myCreatedVariable release];

Кстати, это полезно знать и при использовании массивов.Как только объект, созданный с помощью функций alloc и init, добавляется в массив, он сохраняется в массиве, поэтому вы можете освободить свой экземпляр после добавления его в массив.

В обоих случаях retainCount будет тогда1, как и ожидалось.

если ваше свойство определено с помощью атрибута 'copy', вы также можете освободить объект и даже убить его, так как он был полностью скопирован и сохранен один раз.(Я думаю, что что-то есть, если вы используете сборщик мусора вместо управляемой памяти ... Для проверки ..)

Наконец, если ваше свойство установлено с атрибутом assign, копируется только адрес объекта,поэтому в этом случае не следует освобождать исходный объект.

Однако не рекомендуется использовать атрибут 'assign', поскольку вы можете устанавливать свойство для объектов, которые вы не создали самостоятельно и которые можно было бы освободить.в любое время, позволяя вашему свойству указывать на поля ...

Наконец, не забывайте, что статические создатели в Какао не возвращают сохраненные объекты .(Это соглашение, исключения могут существовать ...)

пример:

NSArray* myArray = [NSArray array];
self.myProperty = myArray;

В этом случае не выпускайте myArray, это уже сделано в функции создателя.Присвоение его свойству сохранит его (с атрибутом retain или copy).

Надеюсь, это поможет,

Приветствия

0 голосов
/ 09 сентября 2010

Извините?Noooo.Боюсь, программирование пытается узнать то, чего мы не знаем каждый день!

Создатели статики - это удобная функция, облегчающая распределение общих объектов.Многие классы в структуре какао имеют такие функции.Arrays, Dictionary, Paths, ...

Давайте возьмем ваш класс в качестве примера и предположим, что вам часто приходится создавать объекты этого класса.Вы можете написать функцию в вашей реализации 'myClass', например:

+(MyClass*)myClass
{
  MyClass *myNewInstance = [[myNewInstance alloc] init];
  return [myNewInstance autorelease];
}

Затем вы можете переписать свой оригинальный пример как:

..
self.myProperty = [MyClass myClass];
..

Straight!Или вы можете написать метод, подобный

-(void)myFunction
{
  MyClass* myTempObject = [MyClass myClass];
  if (myTempObject) {
    // do something with your temporary object
  }
  // Simply exit, object will be released later on.
}

Он намного короче (мы должны обработать случай, когда создание объекта не удалось).Вы любите и создаете сохраненные объекты или используете другое имя для создателя.Но безопаснее следовать правилу фреймворка, тогда он становится рефлексом при кодировании.См. Такие методы, как [словарь NSDictionary], [массив NSArray], [массив NSArrayWithObjects:], ...

Cheers

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