我想在我的类中使用单例模式,它有一个带有参数的私有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我被斯威夫特困住了:
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
}
}我想我还在用目标-c的方式思考,无法用斯威夫特来理解它。有什么帮助吗?
发布于 2016-10-26 18:23:45
您可以通过创建static sharedInstance属性private并使用方法返回现有实例(可选地更改其属性值)或初始化新实例和设置其属性值来定义一个或多个参数的单例。例如,我还将您的config属性设置为只读:
typealias ASTConfig = String
class Asteroid {
private static var sharedInstance: Asteroid!
var config: ASTConfig?
private init(config: ASTConfig?) {
self.config = config
Asteroid.sharedInstance = self
}
static func shared(config: ASTConfig? = "Default") -> Asteroid {
switch sharedInstance {
case let i?:
i.config = config
return i
default:
sharedInstance = Asteroid(config: config)
return sharedInstance
}
}
}
let asteroidA = Asteroid.shared()
asteroidA.config // Default
let asteroidB = Asteroid.shared(config: "B")
asteroidA.config // B通过将config属性的setter定义为private,可以使其属性只读.
private(set) var config: ASTConfig?...but调用shared(config:)的人仍然能够更改配置。为了防止这种情况,您需要将shared(config:)作为抛出方法:
typealias ASTConfig = String
class Asteroid {
enum E : Error {
case config(message: String)
}
private static var sharedInstance: Asteroid!
private(set) var config: ASTConfig?
private init(config: ASTConfig?) {
self.config = config
Asteroid.sharedInstance = self
}
static func shared(config: ASTConfig? = nil) throws -> Asteroid {
switch (sharedInstance, config) {
case let (i?, nil):
return i
case _ where sharedInstance != nil && config != nil:
throw E.config(message: "You cannot change config after initialization!")
case let (nil, c?):
sharedInstance = Asteroid(config: c)
return sharedInstance
default:
sharedInstance = Asteroid(config: "Default")
return sharedInstance
}
}
}
let asteroidA = try! Asteroid.shared(config: "A")
asteroidA.config // A
let asteroidB = try! Asteroid.shared()
asteroidB.config // A
do {
let asteroidC = try Asteroid.shared(config: "C")
} catch {
print(error) // "config("You cannot change config after initialization!")\n"
}
//asteroidB.config = "B" // Error: Cannot assign to property: 'config' setter is inaccessiblehttps://stackoverflow.com/questions/28429544
复制相似问题