Как избавиться от своего собственного sharedInstance в Objective-C? - PullRequest
1 голос
/ 31 января 2009

Если у меня есть класс, имеющий собственный sharedInstance (шаблон синглтона) или общий экземпляр другого класса, как мне убедиться, что общий экземпляр выпущен должным образом при выходе из моей программы? А еще лучше, можете ли вы указать мне некоторую документацию по этому поводу?

пример класса (для ясности все остальные методы удалены):

@interface Foo : NSObject {
}
+ (Foo*)sharedInstance;

@end

.m файл:

static Foo* SharedInstance;

@implementation Foo

+ (Foo*)sharedInstance
{
    if (!SharedInstance)
        SharedInstance = [[Foo alloc] init]; // possible memory leak?

    return SharedInstance;
}
@end

В вышеприведенном коде, когда я могу выпустить SharedInstance?

Ответы [ 4 ]

7 голосов
/ 31 января 2009

Если нет ресурсов помимо общего экземпляра, которые необходимо освободить (например, файлы, уведомления при очистке и т. Д.), Вы можете просто позволить очистить память для sharedInstance при выходе из приложения. Даже файлы, сетевые сокеты и т. Д. Будут очищаться ОС при выходе из приложения, так что вы могли бы уйти, не очистив и их тоже.

Если у вас есть действия по очистке, которые необходимо выполнить до выхода из приложения, вам придется добавить cleanup или somesuch метод к вашему общему экземпляру и статический метод для освобождения общий экземпляр.

5 голосов
/ 03 февраля 2009

Обычно нет необходимости что-либо очищать при выходе, как указал Барри, но вы можете настроить делегат NSApplication, который реализует

- (void)applicationWillTerminate:(NSNotification *)aNotification

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

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

1 голос
/ 29 марта 2011

Что бы вы ни делали, не делайте авто-релиз незарегистрированного общего экземпляра, потому что он будет бесплатным, и вы будете облажаны. Делайте это так, как вы сейчас делаете, но в applicationWillTerminate: поместите что-то вроде этого:

BackgroundFactory * factory = [self sharedFactory];
// prevent an analyzer annoyance
NSValue * value = [NSValue valueWithPointer:factory];
id fac = (id)[value pointerValue];
[fac release];

Обратите внимание, что sharedFactory - это метод, возвращающий общий экземпляр. Весь этот код должен идти в метод + freeSharedInstance.

0 голосов
/ 24 июня 2010

Лучше сделать так

+ (Foo*)sharedInstance
{
    if (!SharedInstance)
        SharedInstance = [[[Foo alloc] init] autorelease];

    return SharedInstance;
}
@end

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

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