Objective-C Синглтон Суперкласс? - PullRequest
0 голосов
/ 13 февраля 2011

Я пытаюсь написать класс, который я могу подклассить, чтобы иметь мгновенный синглтон. Вот что у меня так далеко. Он работает до тех пор, пока один из его подклассов не вызовет другой через sharedInstance, что вызовет огромный цикл, который в конечном итоге исчерпает память.

Есть идеи?

static NSMutableDictionary *sharedInstances = nil;

@implementation Singleton

+ (Singleton*)sharedInstance
{
    [Singleton initSharedInstances];
    Class myClass = [self class];
    Singleton * sharedInstance = [sharedInstances objectForKey:myClass];
    @synchronized(myClass)
    {
        if (sharedInstance == nil)
        {
            sharedInstance = [[myClass alloc] init];
            [sharedInstances setObject:sharedInstance forKey:myClass];
        }
    }
    return sharedInstance;
}

+ (void) initSharedInstances
{
    if (sharedInstances == nil)
    {
        sharedInstances = [[NSMutableDictionary alloc] init];
    }
}

@end

Ответы [ 2 ]

7 голосов
/ 13 февраля 2011

Почему ты все это делаешь? Если вы пытаетесь применить одноэлементное поведение в суперклассе, переопределяя -retain, -release, -retainCount и +allocWithZone:, то вы делаете что-то совершенно ненужное. Гораздо проще просто предоставить метод +sharedInstance и больше ничего не делать. Если пользователь действительно хочет позвонить +alloc / -init, он может, это просто не принесет им пользы. Для примеров этого типа синглтона в каркасах посмотрите NSUserDefaults и NSFileManager (хотя в случае последнего, в эти дни Apple фактически рекомендует вам игнорировать общий экземпляр и выделять / инициализировать ваши собственные экземпляры NSFileManager ).

Чтобы выполнить эту простую работу с общими экземплярами, все, что вам нужно сделать, это реализовать в классе singleton следующее:

+ (id)sharedInstance {
    static MyClass sharedInstance;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        //sharedInstance = [[MyClass alloc] init];
        sharedInstance = [MyClass alloc];
        sharedInstance = [sharedInstance init];
    });
    return sharedInstance;
}
0 голосов
/ 13 февраля 2011

Я пытаюсь написать класс, который мог бы создать подкласс для мгновенного синглтона. Вот что у меня так далеко. Он работает до тех пор, пока один из его подклассов не вызовет другой через sharedInstance, что вызовет огромный цикл, который в конечном итоге исчерпает память.

Звучит так, будто вы описываете взаимную рекурсию. Если subclass1 вызывает subclass2, а subclass2 вызывает subclass1, то вам нужно где-то разорвать цикл, как при простой саморекурсии.

Ваш sharedInstance сам по себе не должен вызывать бесконечную рекурсию, если только метод init, который вы вызываете сам, не вызывает sharedInstance ...

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