Objective C Naming Convention для объекта, который владеет собой - PullRequest
3 голосов
/ 12 мая 2010

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

Если у меня есть метод, подобный + (Foo) newFoo, анализатор видит слово New и сообщает о проблеме в вызывающей стороне, говоря, что newFoo должен вернуть объект с сохранением +1, и он нигде не будет освобожден. Если я назову его + (Foo) getFoo, анализатор сообщит о проблеме в этом методе, заявив, что существует потенциальная утечка, поскольку она не освобождается до возврата.

Мой класс в основном выглядит так:

+ (Foo *) newFoo {
    Foo *myFoo = [[[Foo new] retain] autorelease];
    [myFoo performSelectorInBackground:@selector(bar) withObject:nil];
    return myFoo;
}

- (void) bar {
    //Do something that might take awhile
    [self release];
}

Объект владеет собой и, когда это будет сделано, сам выпустит, но он нигде не хранится, поэтому статический анализатор видит его где-то как утечку. Есть ли какое-либо соглашение об именах или кодировании, чтобы помочь?

1 Ответ

2 голосов
/ 12 мая 2010

В вашей реализации newFoo вы создаете и возвращаете экземпляр Foo с логическим счетом сохранения +1. Какао Правила управления памятью требуют, чтобы методы с префиксом new возвращали сохраненный объект. Но они также утверждают, что владение объектом передается вызывающему методу. Это означает, что вы не можете освободить объект в фоновом потоке.

Позвольте мне предложить более ясный и более какао-ишный способ:

Переименуйте newFoo во что-то вроде fooInBackground (где foo должен быть глаголом). Этот новый метод возвращает автоматически выпущенный экземпляр, позволяя потоку самостоятельно владеть. performSelectorInBackground:withObject: сохраняет и аргумент получателя, и объектный аргумент, поэтому нет оснований сохранять его иначе и вручную освобождать его в фоновом методе.

+ (Foo *) fooInBackground {
    Foo *myFoo = [[[Foo alloc] init] autorelease];
    [myFoo performSelectorInBackground:@selector(bar) withObject:nil];
    return myFoo;
}

Sidenote: Поскольку вы возвращаете объект myFoo из fooInBackground, было бы ошибкой просто освободить его вместо автоматического освобождения объекта перед его возвратом. Фоновый поток может быть завершен до того, как первый поток сможет сохранить myFoo в вызывающем методе. Я просто говорю это, потому что, кажется, существует (необоснованная) озабоченность по поводу автоматического выпуска всех новых программистов iPhone, приезжающих в Какао.

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