беспорядок выпуска/автовыпуска в какао для iPhone

Согласовывайтесь с API, который Вы используете.

5
задан Drew McGhie 14 July 2009 в 14:54
поделиться

6 ответов

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

Мы можем обрабатывать строковый литерал в соответствии с правилами - вам не нужно выпускать его потому что вы им не владеете. Это просто; нет необходимости беспокоиться о том, являются ли они частными случаями или нет, просто следуйте правилам, и все будет в порядке.

Я написал сообщение в блоге с коллекцией статей о правилах управления памятью Какао

117671]; Я бы рекомендовал просмотреть некоторые ссылки.

Я написал сообщение в блоге с коллекцией статей о правилах управления памятью Какао ; Я бы рекомендовал просмотреть некоторые ссылки.

Я написал сообщение в блоге с коллекцией статей о правилах управления памятью Какао ; Я бы рекомендовал просмотреть некоторые ссылки.

10
ответ дан 18 December 2019 в 09:09
поделиться
  1. Я никогда не выпускал строковые константы вроде NSString * foo = @ "x"; . По логике, если бы вам пришлось выпустить результат этого, вы должны были бы освободить параметр для initWithString и оба параметра для initWithFirstName : lastName: тоже.
  2. Вы должны выполнить release или autorelease firstName и lastName . Я видел предупреждения об использовании синтаксиса свойств в деструкторах, и я думаю, это та же самая причина, по которой вы не используете виртуальные функции в конструкторах и деструкторах C ++.

Ваше предположение было неверным. Вы должны сделать это:

    Person *Me = [[Person alloc] initWithFirstName: @"Drew"
                                          lastName: @"McGhie"];
    ...
    [Me release];

или это:

    Person *Me = [Person personWithFirstName: @"Drew"
                                    lastName: @"McGhie"];

... и убедиться, что ваш объект Person правильно обрабатывает + personWithFirstName: lastName: , т.е. [[[self alloc] initWithFirstName: firstName lastName: lastName] autorelease] .

Вам, вероятно, следует сделать вариант с меньшим количеством кода. Ясность важна, NSAutoreleasePool , вероятно, никогда не будет вашим узким местом, и, если это когда-нибудь случится, его легко исправить.

Я думаю, что люди прилагают много усилий, чтобы избежать сообщений класса, которые возвращают автозапуск Не заслужил возражения. Это преждевременная оптимизация, поскольку в ней, вероятно, нет необходимости и, возможно, даже не совсем правильно. И его сложнее поддерживать, вы, скорее всего, будете вечно преследовать утечки.

Кроме того, вы собираетесь автоматически выпустить объект, который вы должны были init (т.е. alloc + initPersonWithFirstName: lastName: вместо использования сообщения класса типа personWithFirstName: lastName: ), я бы посоветовал вам сделать это немедленно. В противном случае вы потенциально можете преследовать такую ​​же утечку. Поэтому, если вы не собираетесь добавлять метод personWithFirstName: lastName: к Person , сделайте это вместо этого:

    Person *Me = [[[Person alloc] initWithFirstName: @"Drew"
                                           lastName: @"McGhie"] autorelease];

Резюме: Какао очень помогает вам с управлением памятью. Убедитесь, что вы не боретесь с этим.

Обновлено на основе отзыва Джона в комментарии.

3
ответ дан 18 December 2019 в 09:09
поделиться

Строки NSS, созданные с помощью синтаксиса @ "String here" , являются постоянными строками. Они отличаются от обычных струн. Как и обычные константные строки C, они создаются при загрузке вашей программы и существуют в течение всего ее срока службы. Класс NXConstantString, к которому они принадлежат, игнорирует все сообщения управления памятью. Вы можете сохранить и освободить их сколько угодно, и это не будет иметь никакого значения.

Для строки, созданной с помощью [[NSString alloc] initWith .. .] -типа, применяются обычные правила управления памятью . Я настоятельно рекомендую прочитать связанные документы - они не сложные, и после их прочтения вы будете знать почти все, что вам когда-либо понадобится об управлении памятью Какао.

2
ответ дан 18 December 2019 в 09:09
поделиться

Сначала последняя часть: вам действительно нужно будет автоматически / освободить Me . Однако вам также необходимо добавить [firstName release]; и [lastName release]; в -dealloc ; или еще лучше; self.firstName = nil;

Что касается строковых литералов; эта часть становится немного сложной, но [выпуск @ "String literal"] , по сути, пустяк. Таким образом, существует разница между двумя временными объектами, но, поскольку вы обычно не знаете, с каким из них будете иметь дело, добавление [temp release]; обычно является безопасным выбором, если вы не знаете, что он будет содержать автоматически выпускаемый объект.

1
ответ дан 18 December 2019 в 09:09
поделиться

О firstName / lastName.

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

@interface Person : NSObject
{
    NSString *firstName;
}
@property (retain) NSString *firstName;
@end

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

- (id) initWithFirstName:(NSString*) aString
{
    self.firstName = aString; 
}

, а метод dealloc - так:

- (void) dealloc
{
     self.firstName = nil;
}

Об объектах типа @ "". Это постоянные объекты NSStrings. Просто используйте их как были (они есть) объекты NSString и никогда не выпускайте их. Компилятор позаботится о них.

1
ответ дан 18 December 2019 в 09:09
поделиться

Класс NSString автоматически вызывает автоматическое освобождение как часть назначения?

Класс NSString ничего не сделал, потому что вы не отправили ему сообщение. Все, что вы сделали, это присвоили переменной. NSString не узнает об этом, и это не его дело.

Кроме того, есть ли разница между двумя объектами * temp после этих операторов? Они оба содержат одну и ту же строку, но существуют ли способы использования памяти / использования, где они различаются?

Они оба являются NSStrings, оба содержат одно и то же значение, и оба считаются неизменяемыми. Это все, о чем вы должны когда-либо заботиться.

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

 @property NSString * firstName;
@property NSString * lastName;

- (void) dealloc
{
 //ВОТ!!!!

 [супер-освобождает];
}

Полагаю, мне не нужно добавлять [firstName release] и [lastName release] (на // ЗДЕСЬ !!!! ), поскольку это автоматически обрабатывается свойствами. Это верно?

Нет. NSObject не выдаст за вас все значения ваших свойств; вам все равно нужно освободить их там.

Также не выполняйте self.firstName = nil и self.lastName = nil в dealloc . Они преобразуются в сообщения (в ваши методы доступа), и когда вы делаете это в dealloc , вы отправляете сообщения полу- dealloc ked объекту. Это напрашивается на неприятности. То же самое относится и к другому способу инициализации значений свойств в init :

1
ответ дан 18 December 2019 в 09:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: