分配共享实例(单个)的正确方法? [英] Correct way to alloc shared instance (singleton)?

查看:51
本文介绍了分配共享实例(单个)的正确方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在查看单例,并且对查看文档,书籍和书籍的正确方法感到好奇.网络上似乎有几种使用方法.

I am looking at singletons and I was curious about the correct way to do the alloc, from looking at the docs, books & web there seems to be a few few methods in use.

M1:

static ReactorClass *sharedReactor = nil;
+(ReactorClass *)sharedInstance {
    if(sharedReactor == nil) {
        sharedReactor == [[ReactorClass alloc] init];
    }
    return sharedReactor;
}

M2:

static ReactorClass *sharedReactor = nil;
+(ReactorClass *)sharedInstance {
    if(sharedReactor == nil) {
        sharedReactor == [[super allocWithZone:NULL] init];
    }
    return sharedReactor;
}

M3:

static ReactorClass *sharedReactor = nil;
+(ReactorClass *)sharedInstance {
    if(sharedReactor == nil) {
        sharedReactor == [[[self class] alloc] init];
    }
    return sharedReactor;
}

非常感谢...

加里

推荐答案

在这种情况下,使用[自类]确实是一种浪费-除非涉及到子类,否则M1和M3并没有太大的不同.其余的实现还没有完成.

Using [self class] is really a waste in this case - M1 and M3 aren't really that different unless you have subclasses involved, and the reality is that the rest of the implementation isn't up to it.

考虑如果创建像这样的ReactorClass的子类会发生什么:

Consider what happens if you create a subclass of ReactorClass like this:

@interface MyReactorClass : ReactorClass {}
@end
@implementation MyReactorClass
@end

如果调用[MyReactorClass sharedInstance],则可以看到它是从单个静态变量sharedReactor中读取的.没关系,如果您仅创建一个子类,但是您需要非常注意这一点,那么您所调用的任何第三方库也不会对它们创建的单例使用相同的基类,但您对此一无所知.如果按照Mark的建议,如果将M3代码复制到子类中,它将更好地工作,但是您需要问自己为什么要对此子类化?"-您获益甚少,最好完全编码而不是依赖超类的实现细节.

If you call [MyReactorClass sharedInstance] you can see that its reading from a single static variable sharedReactor. Thats ok if you only create one subclass but you need to be very conscious of that, and the fact that any 3rd party libraries you call don't also use the same base class for the singletons they create but you don't know about. If, as Mark suggested, you copy the M3 code into your subclass, it will work better but you need to ask yourself "why did I subclass this?" - you got little benefit and would have been better off coding it completely, instead of relying on the implementation details of the superclass.

要正确执行此操作,您需要保留一个静态字典(在基类的+ initialize期间创建),并在其中插入要创建的单例的实际类作为键的项.

To do it properly, you'd keep a static dictionary (create during the +initialise of the base class), and insert entries into it keyed by the actual class of the singleton you were creating.

担心是重写alloc还是allocWithZone:还是一个子类,但实际上,从单例超类继承然后修改其分配方法的任何人都应该得到它们的不良行为.如果要编写完美的单例基类代码,则应创建DODOCMENT并调用其他方法,以便子类生成器可以解决他们可能想到的任何问题,而不会弄乱您的基础结构.

Worrying about whether to override alloc or allocWithZone: is again a subclassing thing but really, anyone who inherits from a singleton superclass and then screws around with its allocation methods deserves the bad behaviour they get. If you want to code the perfect singleton base class, you should create and DOCUMENT additional methods that get called so that subclassers can solve any problem they might think of without messing with your infrastructure.

我个人而言,我的单例以init开头的所有 all 方法抛出异常,并以未知方法(它们称为_init)进行真正的初始化-保证人们滥用单例类的保证不不会得到意想不到的行为.

Personally, my singletons throw exceptions out of all methods starting with init and do their real initialisation in an unknown method (ok, its called _init) - that GUARANTEES that people misusing the singleton class don't get unexpected behaviour.

它实际上可以归结为您对子类生成器有多信任".如果假设他是个白痴,则需要覆盖释放,保留等内容.如果假设他遵循内存管理规则,则可以不理会这些事情,因为它们会起作用.在这方面,Apple的示例代码确实有点愚蠢.它们有些偏执,但远不能防白痴.

It really boils down to "how much do you trust your subclasser". If you assume he's an idiot, you need to override things like release, retain, etc. If you assume he follows the memory management rules, you can leave those things alone because they'll just work. Apple are really a bit stupid in this regard in their sample code; they are somewhat paranoid but nowhere near idiot-proof.

这篇关于分配共享实例(单个)的正确方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆