swift – 具有参数的Singleton和init

我想在我的类中使用具有私有init参数的单例模式.它还有一个名为setup的类函数,用于配置和创建共享实例.我的目标c代码是:
@interface MySingleton: NSObject

+ (MySingleton *)setup:(MyConfig *)config;
+ (MySingleton *)shared;
@property (readonly,strong,nonatomic) MyConfig *config;

@end


@implementation MySingleton

static MySingleton *sharedInstance = nil;

+ (MySingleton *)setup:(MyConfig *)config {
    static dispatch_once_t oncetoken;
    dispatch_once(&oncetoken,^{
        sharedInstance = [[self alloc] initWithConfig:config];
    });

    // Some other stuff here

    return sharedInstance;
}

+ (MySingleton *)shared {
    if (sharedInstance == nil) {
        NSLog(@"error: shared called before setup");
    }
    return sharedInstance;
}

- (instancetype)initWithConfig:(RVConfig *)config {
    self = [super init];
    if (self) {
        _config = config;
    }
    return self;
}

@end

我被困在Swift:

class Asteroid {
    var config: ASTConfig? // This actually should be read-only

    class func setup(config: ASTConfig) -> Asteroid {
        struct Static {
            static let instance : Asteroid = Asteroid(config: config)
        }

        return Static.instance
    }

    class var shared: Asteroid? {
        // ???
    }

    private init(config: ASTConfig) {
        self.config = config
    }
}

我认为我仍然以客观的方式思考,不能用快速方法来计算出来.任何帮助?

您的Objective-C代码的字面翻译可能是:
private var _asteroidSharedInstance: Asteroid!

class Asteroid {
    private var config: ASTConfig?

    class func setup(config: ASTConfig) -> Asteroid {
        struct Static {
            static var oncetoken: dispatch_once_t = 0
        }
        dispatch_once(&Static.oncetoken) {
            _asteroidSharedInstance = Asteroid(config: config)
        }
        return _asteroidSharedInstance
    }

    class var sharedInstance: Asteroid! {                 // personally,I'd make this `Asteroid`,not `Asteroid!`,but this is up to you
        if _asteroidSharedInstance == nil {
            println("error: shared called before setup")
        }

        return _asteroidSharedInstance
    }

    init(config: ASTConfig) {
        self.config = config
    }
}

或者,在Swift 1.2中,您可以消除静态结构并简化安装程序:

private static var setupOncetoken: dispatch_once_t = 0

class func setup(config: ASTConfig) -> Asteroid {
    dispatch_once(&setupOncetoken) {
        _asteroidSharedInstance = Asteroid(config: config)
    }
    return _asteroidSharedInstance
}

这真的不是一个单身人士. (我怀疑你知道这一点,但我提到为了未来读者的利益).通常单例可以在首次使用的任何地方进行实例化.这是一个场景,它只在一个特定的地方进行实例化和配置,您必须注意在尝试在其他地方使用它.这是非常好奇的做法.我们失去了一些单例功能,但仍然遭受所有传统的单身限制.

很明显,如果你确定,那没关系.但是,如果你有趣的替代品,两个人就跳出来:

>使这个真正的单例:您可以通过在init方法中移动ASTConfig的实例化来实现此目的(消除在使用sharedInstance之前必须调用setup的依赖关系).然后你可以退出设置,只要像你一样使用你的单身.所产生的实现也大大简化.它减少到像:

class Asteroid {
    static let sharedInstance = Asteroid()

    private let config: ASTConfig

    init() {
        self.config = ASTConfig(...)
    }
}

显然,我怀疑恶魔是在这个ASTConfig对象的细节,但是如果你可以做一个正确的单例执行,你可以看到这是更简单(特别是在Swift 1.2).而且上面消除了设置vs sharedInstance问题.消除私人全球.一切都简单一些

话虽如此,我认为你有令人信服的理由这样做.也许有一些关键原因,您必须将ASTConfig对象传递给安装方法,而不是仅在Asteroid类的初始化中实例化.

我只是觉得有必要指出,一个适当的单例将是非常好的(两者都更简单的实现和消除理论竞争条件).
>完全放弃单例模式:假设使用一个合适的单身,如上所述,下一个问题是你是否应该放弃任何剩余的单身,只是实例化一个简单的小行星,你正在调用设置,然后而不是依赖sharedInstance,只是传递给真正需要它的对象.

您已经指定您要手动将Asteroid设置在前面,所以让我们正式确定这种关系,并消除单身人士介绍的许多结构性缺陷(参见What’s Alternative to Singleton或谷歌“单身人士”).

不要误会我我假设你有令人信服的理由按照你的方式做到这一点,如果目前的实现方式适用于你,那没关系.但这是一个非常好奇的做法,在这种做法中,您不用享受所有的好处就承担单身人士的理论责任.

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...