5

我有一个基Store类,其中包含所有商店都继承的许多方法。每个商店都是一个单身人士。现在,每个商店都定义了自己几乎相同的方法:

+ (Store *)instance {
    static SubStore *store = nil;
    if (!store) {
        store = (SubStore *) [[super allocWithZone:nil] init];
        [store setupDefaults];
    }
    return store;
}

有没有办法以一种可以简单地将方法添加到基类并由子类继承的方式来制作单例方法?

4

2 回答 2

5

坚持简单/愚蠢,但使用 dispatch_once。

一旦您尝试使其通用,它就会变得复杂。和越野车。

具有显式类命名的 sharedInstance 方法非常明显,您不太可能在项目中重复多次。

但是,如果您有一个类的许多子类,则转到标识符模型。即抽象存储类上的缓存,可以通过标识符查找存储实例。


我避免使用任何一种+initialize,或者更糟的是,+load这种初始化。两者都是非确定性的,因为它们相对于应用程序中其他子系统的执行顺序可能会因看似无害的变化而变化很大。

具有完全确定性的初始化要好得多。在您的(或其他人之一)中添加一个标注,applicationDidFinishLaunching:在您的应用程序中显式初始化此特定子系统。它易于遵循,在声明和使用中都明确,并且不会随着代码库的发展而以奇怪的方式改变行为。

于 2013-05-16T02:36:23.690 回答
2

static SubStore * store = nil;您可以使用NSMutableDictionary使用类名作为键的 a ,而不是使用一个 store 。

简要地:

#import <Foundation/Foundation.h>

@interface MONStore : NSObject
- (NSString *)nameOfMostPopularItem;
@end

@implementation MONStore

+ (instancetype)sharedStore
{
    // lazy population - not thread safe
    static NSMutableDictionary * stores = nil;
    if (nil == stores) {
        stores = [NSMutableDictionary new];
    }
    NSString * key = NSStringFromClass([self class]);
    if (nil == [stores objectForKey:key]) {
        [stores setObject:[self new] forKey:key];
    }
    return [stores objectForKey:key];
}

- (NSString *)nameOfMostPopularItem
{
    return nil;
}

@end

@interface MONMusicStore : MONStore
@end

@implementation MONMusicStore
- (NSString *)nameOfMostPopularItem { return @"Guitar Strings"; }
@end

@interface MONPetStore : MONStore
@end

@implementation MONPetStore
- (NSString *)nameOfMostPopularItem { return @"Puppies"; }
@end

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        NSLog(@"--- Shopping List ---\nMusic Store:\n\t%@\n\nPet Store:\n\t%@\n",
                    [MONMusicStore sharedStore].nameOfMostPopularItem,
                    [MONPetStore sharedStore].nameOfMostPopularItem
                    );
    }
    return 0;
}

...并不是说我会在我的程序中这样做。

于 2013-05-16T07:15:26.997 回答