Нужно ли устанавливать авторелиз в пределах оператора alloc? - PullRequest
3 голосов
/ 04 июля 2011

Предположим, следующий код:

NSString *str=[[NSString alloc] initWithString:@"sagar"];


[str autorelease];

Я много раз видел, что большинство программистов предпочитают ставить alloc , init одновременно в одном выражении.

Здесь я запрашиваю возможность деления автоматического выпуска для следующего оператора.

  • Например, рекомендуется ставить init с оператором alloc.Это то же самое для autorelease ?

Ответы [ 5 ]

8 голосов
/ 04 июля 2011

Большинство программистов предпочитают помещать alloc, init одновременно в одном выражении.

Это потому, что экземпляр, возвращаемый инициализатором, не обязательно является возвращаемым +alloc.Например, это неправильно и приведет к сбою вашей программы:

NSString *str = [NSString alloc];
[str initWithString:@"sagar"];

, потому что в этом случае -initWithString: вызывает освобождение предыдущего экземпляра, а str в конечном итоге указывает на освобожденный объект.Это можно исправить с помощью:

NSString *str = [NSString alloc];
str = [str initWithString:@"sagar"];

, так что str указывает на другой экземпляр, возвращаемый -initWithString:.Форма:

NSString *str = [[NSString alloc] initWithString:@"sagar"];

гарантирует, что str указывает на правильный экземпляр.

Тем не менее, -autorelease отличается.Если он не был отвергнут злым джинном, он всегда возвращает самого получателя.Это означает, что оба:

NSString *str = [[NSString alloc] initWithString:@"sagar"];
str = [str autorelease];

и:

NSString *str = [[NSString alloc] initWithString:@"sagar"];
[str autorelease];

являются правильными и работают одинаково.

Что касается различия между:

NSString *str = [[[NSString alloc] initWithString:@"sagar"] autorelease];

и:

NSString *str = [[NSString alloc] initWithString:@"sagar"];
…
[str autorelease];

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

NSString *str = [[NSString alloc] initWithString:@"sagar"];
…
return [str autorelease];

, чтобы сделать (более) явным, чтобы метод / функция возвращал объект с автоматическим освобождением.

4 голосов
/ 04 июля 2011

Вы можете сделать это

MyObject* foo = [[MyObject alloc] init];
...
[foo autorelease];
...
return foo;

или это

MyObject* foo = [[MyObject alloc] init];
...
...
return [foo autorelease];

или это

MyObject* foo = [[[MyObject alloc] init] autorelease];
...
...
return foo;

Я бы пошел со вторым или третьим, но этоличные предпочтения.

Если это временный объект, который вы не возвращаете, вы можете сделать это:

MyObject* foo = [[MyObject alloc] init];
...
[foo autorelease];
...
return somethingElse;  

или это

MyObject* foo = [[[MyObject alloc] init] autorelease];
...
...
return somethingElse;    

или это

MyObject* foo = [[MyObject alloc] init];
...
[foo release];
...
return somethingElse;  

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

4 голосов
/ 04 июля 2011

Вы можете использовать автоматическое высвобождение в любом месте области действия, фактически наиболее распространенным является

return [object autorelease]

Когда вы хотите вернуть объект вызывающей стороне.

3 голосов
/ 04 июля 2011

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

0 голосов
/ 24 сентября 2014

Не проблема, если вы поставите autorelease в следующем операторе.

autorelease объект автоматически помещается в пул автоматического выпуска, когда заканчивается область этого объекта.Значит, компилятор автоматически добавляет сообщение release , когда заканчивается область действия этого объекта, и в этом случае вам не нужно писать сообщение release для этого объекта.В пуле автоматического выпуска хранятся объекты, которым отправляется сообщение о выпуске при очистке самого пула.

Application Kit создает пул автообновления в главном потоке в начале каждого цикла цикла событий и сливает его в конце, освобождая тем самым любые автоматически выпущенные объекты, сгенерированные во время обработки события.Если вы используете Application Kit, вам, как правило, не нужно создавать свои собственные пулы.Однако, если ваше приложение создает много временных автоматически выпущенных объектов в цикле событий, может быть полезно создать «локальные» пулы автоматического выпуска, чтобы помочь минимизировать пиковый объем памяти.

В главном потоке, [myObj autorelease] автоматически выбрасывает myObj в пул в конце цикла перикулярного события, управляемого самой системой.Но, чтобы использовать [myObj autorelease] в случае вторичных потоков, вам придется использовать NSAutoreleasePool.В противном случае, если пул недоступен, автоматически освобожденные объекты не освобождаются, и вы теряете память.

Например, для вторичных потоков:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// Code benefitting from a local autorelease pool.

[pool release];

Помните, что никогда не освобождайте объект после самого пулабыл выпущен.Это приведет либо к сбою, либо к неожиданному выводу.Я упоминал об этом, потому что Я заплатил большую цену за эту ошибку.

Если ваш проект разрабатывается в ARC, вам больше не нужно беспокоиться о сохранении, выпуске, авто-выпуске.,Apple рекомендует использовать среду ARC.

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