Objective-C - 动态单例初始化器?

Ste*_*all 5 inheritance objective-c ios

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

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

有没有办法以一种方式来创建单例方法,该方法可以简单地添加到基类并由子类继承?

bbu*_*bum 5

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

一旦你试图使它变得通用,它就会变得复杂.而且越野车.

具有显式类命名的sharedInstance方法显而易见,并且您不太可能在项目中重复多次.

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


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

完全确定性初始化要好得多.在您的applicationDidFinishLaunching:(或其中一个)中添加一个标注,在您的应用中显式初始化此特定子系统.它很容易遵循,在声明和使用中都是明确的,并且在代码库发展时不会以奇怪的方式改变行为.

  • @zneak这不是真的.如果你有一个带有`initialize`方法的类A和一个扩展A的类B,而类B没有实现`initialize`方法,那么类A的`initialize`方法将被调用两次 - 一次当A是第一个时引用和首次引用B时. (3认同)

jus*_*tin 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;
}
Run Code Online (Sandbox Code Playgroud)

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