我正在创建像这样的单例实例
static let currentUser = User()
private override init() {
super.init()
// custom initialisation
}
如何重置此实例或重新设置为nil?
答案 0 :(得分:33)
我使用optional
Singleton实例创建我的所有单身人士。
但是我也使用private
并使用函数来获取它。
如果Singleton为nil
,则会创建一个新实例。
这实际上是设置Singleton的唯一好方法。如果你有一个常规对象,你无法取消初始化它是一个内存问题。单身人士没有什么不同,除了你必须写一个功能来做它。
单身人士必须完全自我管理。这意味着从init到deinit。
我在github上为Singeltons提供了几个模板,其中一个模板具有完全实现的读/写锁定。
class Singleton {
private static var privateShared : Singleton?
class func shared() -> Singleton { // change class to final to prevent override
guard let uwShared = privateShared else {
privateShared = Singleton()
return privateShared!
}
return uwShared
}
class func destroy() {
privateShared = nil
}
private init() {
print("init singleton")
}
deinit {
print("deinit singleton")
}
}
答案 1 :(得分:7)
如果您将Settings.renderSchema = false
声明为currentUser
,则无法执行此操作。它应该是let
,或者更好,var
。此外,如果private (set) var
的类型为currentUser
,则无法将nil
指定为User
(根据您此刻分配的方式推断)。相反,它应该是User?
。
例如,像这样:
/// ...
static private (set) var currentUser: User? = User()
static func resetCurrentUser() {
currentUser = nil
}
// ...
private (set)
仅允许在当前文件范围内更改属性,对于其余代码,它将被视为let
。然后可以使用方法resetCurrentUser()
将其放入nil
。
甚至这个:
// ...
private static var _currentUser: User?
static var currentUser: User {
if _currentUser == nil { _currentUser = User() }
return _currentUser!
}
static func resetCurrentUser() {
_currentUser = nil
}
// ...
您可以将currentUser
作为计算属性来保证返回值。因此,您可以将用户重置为nil
,是的。但是如果以后再次尝试从那里读取,则会自动创建一个新实例。
但要注意多线程访问。
答案 2 :(得分:3)
所有你想要的都是可能的,但是高度推荐:)因为设计中的单身人士不应该回到零。
首先,如果您要更改currentUser
,则必须为var
。然后,如果你想要它是nil,它必须是可选类型,你应该在使用时解开它。
static var currentUser: User? = User()
我建议不要更改currentUser
或将其设为非静态(例如,某些UsersManager
的属性。
您还可以更改currentUser
的属性(例如name
,loggedIn
)。最后,看一下这个答案:https://stackoverflow.com/a/28398974/326017 - 它描述了你的情况。
答案 3 :(得分:0)
可接受的答案有效,但是如果您不希望处理可选内容,则可以创建一个private
设置器:
class Singleton {
static private(set) var shared: Singleton
static func reset() {
shared = Singleton()
}
private init() {
print("init singleton")
}
deinit {
print("deinit singleton")
}
}