Эффект 'myObj = [[[MyClass alloc] init] autorelease] retain];'? - PullRequest
6 голосов
/ 01 сентября 2010

Я только что скачал Facebook iOS SDK и заметил, что в примере кода, который поставляется с SDK, каждый раз, когда он создает экземпляр класса Facebook, он делает это так:

_facebook = [[[[Facebook alloc] init] autorelease] retain];

где _facebook - это переменная-член вызывающего объекта (т.е. не локальная переменная).

Может кто-нибудь объяснить, в чем смысл автоматического освобождения, а затем сохранить его?

Ответы [ 2 ]

13 голосов
/ 01 сентября 2010

Он фактически не делает ничего, кроме потребления некоторых циклов и памяти.

Или, точнее, в правильно написанном приложении ничего не делает. В неправильно написанном приложении оно может маскировать ошибку, увеличивая срок службы объекта _facebook. Тем не менее, это не реальное исправление.

Я нашел похожую строку кода в http://github.com/facebook/facebook-ios-sdk/blob/master/sample/DemoApp/Classes/DemoAppViewController.m Если это то, на что вы ссылаетесь, то да, это чепуха.

1 голос
/ 24 июня 2012

Хотя возможно, что код, который вы обнаружили, был просто небрежным, этот шаблон ДЕЙСТВИТЕЛЬНО имеет значение.

«alloc, autorelease, retain» подразумевает, что на объект ссылаются в двух местах:

  • В качестве возвращаемого значения в стеке вызовов (стиль автоматического выпуска)
  • Само по себе FB SDK ('retain')

Это имеет значение, если две ссылки могут бытьвыпущен самостоятельно.Например, если SDK может освободить свою ссылку ДО того, как стек вызовов завершит работу и опустошит пул автоматического выпуска.Хорошо, это довольно нюанс;что я имею в виду?

Рассмотрим следующие случаи:

A) фактический код

_facebook = [[[[Facebook alloc] init] autorelease] retain];

_facebook теперь имеет счет сохраненияиз 2, и ожидает 2 вызова для «освобождения»: 1 от того, кто назвал «сохранить», и 1 в какой-то момент в будущем, когда NSAutoreleasePool истощает.

B) простой »альтернативный "предложенный (НЕ эквивалентный)

_facebook = [[Facebook alloc] init];

_facebook имеет счет сохранения 1 и будет уничтожен при вызове 'release' (потенциально большая проблема, если пул авто-выпуска не имеет ')еще не истощен, а стек вызовов все еще использует объект)

Почему это важно?Представьте себе такой код:

@implementation (Thinger)
+(id) make_new_thing
{
    return my_copy_of_thing = [[[[Thing alloc] init] autorelease] retain];
}
+(id) forget_about_thing
{
    if (my_copy_of_thing != nil) {
        [my_copy_of_thing release];
        my_copy_of_thing = nil;
    }
}
@end


void foo() {
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    id thing = [Thinger make_new_thing];
    [Thinger forget_about_thing];
    ...
    [thing useThing]; // implementation B would break here !
    [pool drain];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...