Подробнее об освобождении собственности - PullRequest
0 голосов
/ 31 января 2012

Может быть, кто-то может объяснить разницу между свойствами:

в .h файле

@property(nonatomic,retain) NSString *someString;
@property(nonatomic,retain) NSString *someString2;

в .m файле

@synthesize someString = _someString;

или

@synthesize someString2;

Какая разница для _someString и self.someString2, используемых в контроллере?и в dealloc как я должен освободить эти свойства

[_someString release];

И

[self.someString2 release];

ИЛИ

_someString = nil;
_someString2 = nil;

Ответы [ 5 ]

5 голосов
/ 31 января 2012
synthesize someString = _someString;

Это говорит о синтезировании свойства someString, но для прямого доступа используйте _somestring.

synthesize someString2;

Это говорит о синтезировании свойства someString2, но для прямого доступа используйте someString2.

Думайте об этом так, как будто компилятор генерирует iVars для вас, но в первом случае iVar называется _someString, а второй - someString2

Это обычное явление.использование (я недавно перешел к нему), так что когда вы имеете дело с объектом напрямую (например, инициализаторами или в dealloc, где вы не должны использовать self), вы можете сразу увидеть, что когда вы пишете _someString = @"aString";, выне проходят через методы свойств, которые бы применяли типы управления памятью (такие как сохранение или копирование).Обычно люди назначали значения напрямую, а затем задавались вопросом, почему они не были сохранены.

[_someString release];
[_someString2 release];

Отправляет метод release непосредственно объекту.

self.someString = nil;
self.someString2 = nil;

Отправляет релиз через собственность.В этом случае нет никакой разницы.Если бы вы выделяли объекты, разница была бы: например:

_someString = someOtherString;

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

self.someString = someOtherString;

не пропускает ничего, потому что синтезированный установщик освободит текущий объект перед установкой (и сохранением) нового объекта.

Я сказал, что Iпришел в АРК.В этом случае вы все равно не можете вызвать release, поэтому вопросов не возникает, но _someString = someOtherString не является утечкой, потому что компилятор будет заниматься выпуском текущего объекта для вас.

1 голос
/ 31 января 2012

После:

property(nonatomic,retain) NSString *someString;
property(nonatomic,retain) NSString *someString2;

и:

@synthesize someString = _someString;
@synthesize someString2;

someString - это свойство, поддерживаемое переменной экземпляра _someString.Сохранение и освобождение памяти управляется Obj-C.

  • Присваивания someString должны использовать форму self.someString внутри класса и должны использовать <reference>.someString вне его.За исключением случаев, когда в инициализаторе никогда не должно быть любых назначений для простого _someString.
  • Для чтения значения можно использовать просто _someString в классе, но self.someString также допустимо,и должен использовать <reference>.someString вне его.
  • Для освобождения значения необходимо использовать форму self.someString = nil внутри класса и <reference>.someString = nil вне его.

someString2 аналогично, за исключением того, что оно поддерживается автоматически именуемой переменной экземпляра, которая называется someString2.

1 голос
/ 31 января 2012

@ synthesize someString = _someString; Означает, что вы создаете свойство с другим именем, а не с переменной-членом, с которой оно связано. Это отлично. Как правило, они имеют одно имя. Вот пример, когда это не так. Так что someString будет вашим свойством, а _someString - вашей переменной-членом.

Что касается [_someString release]; и [self.someString2 release]; вы видите, что release вызывается для переменной-члена вашего класса (_someString). [self.someString2 release] вызывает release для любого возвращаемого свойства. Имейте в виду, что свойства могут сделать больше, чем просто получить и установить. Это методы, как и любой другой, который вы могли бы исправить.

Кроме того, не делайте [self.someString2 release]; Вместо этого сделайте self.someString2 = nil; Это выпустит это от вашего имени. Таким образом, это обнуляет строку. Это защитит вас от доступа к плохой памяти, если строка фактически освобождена.

0 голосов
/ 31 января 2012
[_someString release];

И

[self.someString2 release];

выпускает дважды, это неправильно. Используйте

_someString = nil;
_someString2 = nil;

просто устанавливает ваши ивары на ноль, они не освобождают их, так что это опять неправильно.

Правильно: либо

self.someString = nil;
self.someString2 = nil;

или

[_someString release];
[_someString2 release];

Я бы порекомендовал первый (точка-нотация), так как он работает правильно (вы не знаете, какой код генерирует компилятор при синтезировании ваших методов доступа ...)

0 голосов
/ 31 января 2012

_someString = nil не освободит вашу собственность.

В этом случае _someString и self._someString указывают на один и тот же объект, поэтому вы можете освободить, используя либо.

...