我有一个单身人士:
public class Manager {
static let shared = Manager()
private init() {
...
}
}
其他类可以通过以下方式访问它:
Manager.shared
这里没问题。现在,我开始思考,如果私有初始化程序是可抛出的,该怎么办?
public class Manager {
// Compiler error: Call can throw, but erros cannot be thrown out of global variable initializer
static let shared = Manager()
// throwable initialier
private init() throws {
...
}
}
如果我仍然希望Manager
成为单身人士,如何解决上述错误?
答案 0 :(得分:3)
许多可能的解决方案之一可能是让共享变量为Optional
并使用try?
关键字调用初始值设定项。
像这样:
public class Manager {
static let shared: Manager? = try? Manager()
// throwable initialier
private init() throws {
...
}
}
编辑:
如果您想在上次调用init
时失败,尝试重新创建对象,则可以编写类似这样的内容。
public class Manager {
static var shared: Manager? {
get {
if instance == nil {
instance = try? Manager()
}
return instance
}
}
static private var instance: Manager? = try? Manager()
// throwable initialier
private init() throws {
...
}
}
答案 1 :(得分:1)
你看到的错误很清楚。如果您不理解,我建议您阅读投掷函数的文档here。
有几种方法可以解决这个问题,问题是 - 为什么你会为单例对象抛出标记初始化器...你可以做的一件事就是将初始化器包装成setupManager
函数,就像这样:
public class Manager {
static let shared = setupManager()
// throwable initialier
private init() throws {
}
static func setupManager() -> Manager {
do {
return try Manager()
} catch let error {
fatalError("error:\(error)")
}
}
}
在没有设置方法的较短声明中:
public class Manager {
static var shared: Manager {
do {
return try Manager()
} catch let error {
// Immediatly stops program execution...
fatalError("An error occured: \(error)")
}
}
// throwable initialier
private init() throws {
}
}
解决这个问题的另一种方法是使用try?并使共享实例可选(在我上面发布的文档中找到):
public class Manager {
static let shared: Manager? = try? Manager()
// throwable initialier
private init() throws {
}
}
其他方面可能是强制解开它,但这不是你想要做的,因为它对问题的解决方法非常糟糕......
请记住,总是当你编写代码时,修复问题的核心,而不是症状,它总是会变得更糟。在任何情况下,我都没有看到任何使单身初始化器抛出的原因,所以如果您依赖于应用程序中应该交给它的一些代码,请重新考虑您的体系结构。欢迎提出问题。祝你编码愉快!
答案 2 :(得分:0)
获取单例实例意味着您不知道它是否已经启动。如果它的throwable意味着你想跟踪。
这里有一个你可以遵循的解决方案。
enum SomeError: Error {
case unknown
}
public class Manager {
private static var sharedManger: Manager? = {
do {
let manager = try Manager()
return manager
} catch {
return nil
}
}()
private init() throws {
...
}
class func shared() throws -> Manager {
if let sm = sharedManger {
return sm
} else {
throw SomeError.unknown
}
}
}
现在你可以做类似
的事情了do {
try Manager.shared()
} catch {
print("Throw")
}