gpt4 book ai didi

swift - 单例和带参数的初始化

转载 作者:IT王子 更新时间:2023-10-29 05:10:00 25 4
gpt4 key购买 nike

我想在我的类中使用单例模式,它有一个带参数的私有(private) init。它还具有一个名为 setup 的类函数,用于配置和创建共享实例。我的 objective-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 的方式思考,无法用 swift 解决。有帮助吗?

最佳答案

我有一个稍微不同的解决方案。这依赖于

  1. 静态变量被延迟初始化
  2. 使用 Config 结构来存储初始化参数
  3. 在 init 中使用 fatalError 强制执行设置调用(如果在访问单例之前未调用设置调用)

.

class MySingleton {

static let shared = MySingleton()

struct Config {
var param:String
}
private static var config:Config?

class func setup(_ config:Config){
MySingleton.config = config
}

private init() {
guard let config = MySingleton.config else {
fatalError("Error - you must call setup before accessing MySingleton.shared")
}

//Regular initialisation using config
}
}

要使用它,你需要设置

MySingleton.setup(MySingleton.Config(param: "Some Param"))

(显然,如果需要,您可以通过扩展 MySingleton.Config 结构来使用多个参数)

然后要访问单例,您可以使用

MySingleton.shared

我对必须使用单独的设置结构并不狂热,但我喜欢它接近推荐的单例模式。将设置结构保留在单例中可以使事情变得相当干净。

注意 - 共享对象是单例。在后台,swift 使用 dispatchOnce 来保证这一点。然而,没有什么可以阻止您使用来自不同线程的不同配置多次调用设置。

目前,对 shared 的第一次调用将“锁定”设置。

如果你想在第一次调用 setup 后锁定东西,那么只需调用

_ = MySingleton.shared

设置中

简单示例:

class ServerSingleton {
static let shared = ServerSingleton()

struct Config {
var host:String
}
private static var config:Config?

let host:String

class func setup(_ config:Config){
ServerSingleton.config = config
}

private init() {
guard let config = ServerSingleton.config else {
fatalError("Error - you must call setup before accessing MySingleton.shared")
}

host = config.host
}

func helpAddress() -> String {
return host+"/help.html"
}
}

ServerSingleton.setup(ServerSingleton.Config(host: "http://hobbyistsoftware.com") )
let helpAddress = ServerSingleton.shared.helpAddress()
//helpAddress is now http://hobbyistsoftware.com/help.html

关于swift - 单例和带参数的初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28429544/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com