你会调用这个实现在Objective-C“优雅”一个多例吗?我有编程“不允许”使用allocallocWithZone:的,因为决定分配或不分配内存需求基于一键来完成。

我肯定知道,我需要工作,只有两种情况,所以我使用的不是地图“的switch-case”。

#import "Multiton.h"

static Multiton *firstInstance = nil;
static Multiton *secondInstance = nil;

@implementation Multiton

+ (Multiton *) sharedInstanceForDirection:(enum KeyName)direction {

    return [[self allocWithKey:direction] init];
}

+ (id) allocWithKey:(enum KeyName)key {

    return [self allocWithZone:nil andKey:key];
}

+ (id) allocWithZone:(NSZone *)zone andKey:(enum KeyName)key {

    Multiton **sharedInstance;

    @synchronized(self) {

        switch (key) {
            case KEY_1:
                sharedInstance = &firstInstance;
                break;
            case KEY_2:
                sharedInstance = &secondInstance;
                break;
            default:
                [NSException raise:NSInvalidArgumentException format:@"Invalid key"];
                break;
        }
        if (*sharedInstance == nil)
            *sharedInstance = [super allocWithZone:zone];
    }

    return *sharedInstance;
}

+ (id) allocWithZone:(NSZone *)zone {

    //Do not allow use of alloc and allocWithZone
    [NSException raise:NSObjectInaccessibleException format:@"Use allocWithZone:andKey: or allocWithKey:"];
    return nil;
}

- (id) copyWithZone:(NSZone *)zone {

    return self;
}

- (id) retain {

    return self;
}

- (unsigned) retainCount {

    return NSUIntegerMax;
}

- (void) release {

    return;
}

- (id) autorelease {

    return self;
}

- (id) init {
    [super init];
    return self;
}

@end

PS:我没有,如果这作品试用至今,但它的干净编译:)

有帮助吗?

解决方案

我觉得单身是一个坏主意,这看起来大约四倍可怕。该代码是相当复杂的,你可以肯定花了不错的几个小时追逐在这微妙的错误的,你可能永远不会觉得舒服了。这是没有好。您应该抛出这种可憎的路程,在不需要那么多的想法一些其他的方式连接到一起的对象。

如果你喜欢的图案,你可以使用一个类似于工厂模式接线你的对象。该工厂将创建这两个实例,并通过他们需要的地方照顾。而工厂会有很多更简单的比多例:

@interface Factory : NSObject {
    Foo *foo1, *foo2;
}
@end

@implementation Factory

- (id) init {
    [super init];
    foo1 = [[Foo alloc] init];
    foo2 = [[Foo alloc] init];
    return self;
}

当然,你不必一次创建两个实例。你可以做你喜欢有什么 - 缓存,延迟加载,任何东西。该点离开Foo生命周期管理到工厂,从Foo代码分开。然后它变得更容易。 ¶所有其他对象需要Foo将被创建并通过有线工厂和将通过设定器接收它们Foo

@implementation Factory

- (id) wireSomeClass {
    id instance = [[SomeClass alloc] init];
    [instance setFoo:foo1];
    [instance setAnotherDependency:bar];
    return [instance autorelease];
}

这是所有更直接然后从你的问题代码。

其他提示

不覆盖ALLOC。与覆盖ALLOC返回类的以前分配的情况下,你做的问题是,当+ sharedInstance调用[多例的alloc]初始化] ... +页头将返回旧的实例,然后点击 -init会重新初始化!最好的做法是重写-init,做缓存查找和调用[自我释放]你返回缓存实例之前。

如果你的真正的关心额外的+页头的成本(这不是很多),你还做你的缓存查找在+ sharedInstance,然后确保所有的客户端访问对象通过+ sharedInstance以避免额外的alloc。

点顺序:你怎么知道,你永远只能有两种情况,或者需要有两个实例? (或希望有两个实例?)究竟什么是的的有一个“多例”? (而且是,即使一个字?)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top