Для автоматического выпуска или не для автоматического выпуска - PullRequest
12 голосов
/ 30 января 2010

В следующем примере кода из Руководства по программированию основных данных создается NSFetchRequest с autorelease, в то время как NSSortDescriptor не создается с помощью autorelease. Почему NSSortDescriptor не был создан с помощью автоматического выпуска? Это вопрос предпочтений?

NSManagedObjectContext *moc = [self managedObjectContext];    
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Employee" 
                                                     inManagedObjectContext:moc];

NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];
// Set example predicate and sort orderings...
NSNumber *minimumSalary = ...;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(lastName LIKE[c]'Worsley') AND (salary > %@)", minimumSalary];    
[request setPredicate:predicate];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"firstName" 
                                                               ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];
NSError *error;
NSArray *array = [moc executeFetchRequest:request error:&error];
if (array == nil){
    // Deal with error...
}

Ответы [ 5 ]

35 голосов
/ 30 января 2010

Когда вы выполняете автоматический выпуск, вы, в основном, говорите: «Мне это больше не нужно, но кто-то другой может его забрать (до того, как пул автоматического выпуска будет исчерпан)». Когда вы явно ссылаетесь на объект, вы говорите: «Мне это больше не нужно, и если кто-то еще не сказал иначе (приобрел), он должен быть немедленно освобожден».

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

26 голосов
/ 30 января 2010

Для автоматического выпуска или не для автоматического выпуска

То, что - это вопрос.

Будь благороднее, если кодер перенесет стропы и стрелы утечек памяти или возьмете оружие в море защищенных указателей и, сохранив их, покончите с ними ... Это искренне желаемое желание! Да, есть загвоздка! ... Ибо в этих чрезмерно освобожденных объектах то, что может произойти сбой, когда мы ссылаемся на объекты, которых там нет, должно дать нам паузу.

Я не мог с собой поделать. Я возьму повторный удар. Я ничего не жалею!

1 голос
/ 30 января 2010

Объект запроса будет возвращен вызывающей стороне, тогда как sortDescriptor используется, а затем отбрасывается.

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

Стоит задуматься о том, что именно означает авто-релиз. Когда вы вызываете autorelease для объекта, он добавляет объект в список, а когда цикл вашего приложения завершается, для него вызывается release. Это делает автоматический выпуск точно эквивалентным отложенному выпуску.

Отличный документ Apple по управлению памятью, который стоит внимательно прочитать. http://developer.apple.com/iPhone/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

0 голосов
/ 30 января 2010

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

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

В вашем примере кода авто-релиз является лишь мерой безопасности.Объект NSPredicate освобожден, потому что его работа завершена, но кодер хотел убедиться, что объект NSFetchRequest завис.Вам не нужно использовать «autorelease» в этом случае, но если вы потеряли количество своих выпусков, fetchRequest может исчезнуть.С другой стороны, вы не хотите, чтобы он оставался осиротевшим и протекающим, поэтому вы используете автоматическое освобождение для очистки, когда пул, в котором находится объект, сливается.

Наиболее распространенное использование автоматического выпуска - когда вы создаете переменное числообъектов каждый раз.Вы не хотите отслеживать их все, поэтому вы автоматически выпускаете их и позволяете бассейну позаботиться о них.(Более того, вы создаете локальный пул и сливаете его, как только закончите.)

В стандарте Apple API любой метод, который создает новый объект без ключевых слов «init», «new» или'create' возвращает автоматически выпущенный объект.

-[NSString initWithString:] не является автоматическим выпуском, но - [NSString stringWithString:] есть.Это вызывает проблемы в средах, не связанных с сборкой мусора, поскольку stringWithString: возвращает строку, которая, похоже, ведет себя как сохраненный объект, но позже она внезапно исчезнет, ​​по-видимому, наугад, когда пул авто-выпусков был создан в стоках.


Edit01: из документов Apple

Пул автообновления является экземпляром NSAutoreleasePool, который «содержит» другие объекты, получившие сообщение автообновления;когда пул автоматического выпуска освобождается, он отправляет сообщение об освобождении каждому из этих объектов.Объект может быть помещен в пул автоматического выпуска несколько раз и получает сообщение о выпуске каждый раз, когда он помещается в пул.Таким образом, отправка автоматического выпуска вместо выпуска объекта продлевает время жизни этого объекта, по крайней мере, до тех пор, пока сам пул не будет освобожден (объект может просуществовать дольше, если он будет сохранен в промежуточный период).

СохранениеПодсчет и автоматическое высвобождение поддерживают объект живым с помощью одного и того же базового (но отдельного) механизма подсчета.Основное различие заключается в том, какой владелец объекта отправляет релиз.С оставшимися значениями это еще один объект, но для автоматически выпущенных счетчиков - это пул автоматического выпуска.

0 голосов
/ 30 января 2010

Вопрос заключается в следующем: как использование autorelease или release влияет на время жизни объекта?

В обоих ваших примерах это не имеет значения.

И NSFetchRequest, и NSSortDescriptors будут работать до конца метода, независимо от того, выпущены они или выпущены автоматически.

Если вы создаете экземпляр объекта, а затем передаете его другому объекту (скажем, NSArray), он останется живым независимо от того, вызываете ли вы release или autorelease.

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