简体   繁体   English

Objective-C单例超类?

[英]Objective-C Singleton Superclass?

I'm trying to write a class that I can subclass to have an instant singleton. 我正在尝试编写一个可以子类化以具有即时单例的类。 Here's what I have so far. 到目前为止,这就是我所拥有的。 It works until one of its subclasses calls another via sharedInstance which causes a huge loop that eventually runs out of memory. 它一直工作到其子类之一通过sharedInstance调用另一个子类为止,这会导致巨大的循环,最终耗尽内存。

Any ideas? 有任何想法吗?

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

Why are you bothering with all this? 你为什么要烦这些呢? If you're trying to enforce singleton behavior in the superclass by overriding -retain , -release , -retainCount , and +allocWithZone: then you're doing something completely unnecessary. 如果您试图通过覆盖-retain-release-retainCount+allocWithZone:来强制超类中的单例行为,那么您所做的事情完全没有必要。 Far more simple is just to provide a +sharedInstance method and do nothing else. 更简单的是提供一个+sharedInstance方法,什么也不做。 If the user really wants to call +alloc / -init , they can, it just won't do them much good. 如果用户真的想调用+alloc / -init ,那么他们可以做,只是做得不好。 For examples of this type of singleton in the frameworks, look at NSUserDefaults and NSFileManager (though in the case of the latter, these days Apple actually recommends you ignore the shared instance and alloc/init your own instances of NSFileManager ). 有关框架中此类单例的示例,请查看NSUserDefaultsNSFileManager (尽管对于后者, NSFileManager这些天,Apple实际上建议您忽略共享实例并分配/初始化自己的NSFileManager实例)。

In order to do this simple shared instance stuff, all you have to do is, in the singleton class, implement the following: 为了做这些简单的共享实例,您要做的就是在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;
}

I'm trying to write a class that I can subclass to have an instant singleton. 我正在尝试编写一个可以子类化以具有即时单例的类。 Here's what I have so far. 到目前为止,这就是我所拥有的。 It works until one of its subclasses calls another via sharedInstance which causes a huge loop that eventually runs out of memory. 它一直工作到其子类之一通过sharedInstance调用另一个子类为止,这会导致巨大的循环,最终耗尽内存。

This sounds like you are describing mutual-recursion. 听起来您正在描述相互递归。 If subclass1 calls subclass2 and subclass2 calls subclass1 then you need to break the loop somewhere, just as with simple self-recursion. 如果subclass1调用subclass2,而subclass2调用subclass1,则您需要在某个地方中断循环,就像使用简单的自递归一样。

Your sharedInstance itself should not cause infinite recursion unless the init method you invoke itself invokes sharedInstance ... 您的sharedInstance本身不应引起无限递归,除非您自己调用的init方法调用了sharedInstance ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM