单例变量不更新
Singleton variable not updating
下面的视图控制器中变量 'switcheroo' 的值在我尝试通过单例访问它时始终相同。我正在尝试从一个自定义标签 class 访问它的值,该标签一个一个地打印标签的字符。设置标签后,我尝试在 Viewcontroller 单例中获取 switcheroo 的更新值。但是它总是 returns switcheroo 的初始值,而不是更新值(我可以在 viewcontroller 中追踪)。难道我做错了什么?
class TheViewController: UITableViewController, UIGestureRecognizerDelegate, UITabBarControllerDelegate {
static let shared = TheViewController()
var switcheroo = 0
... various operations that change the value of switcheroo...
}
class CustomLabel: UILabel {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override var attributedText: NSAttributedString? {
didSet {
DispatchQueue.main.async {
let characterDelay = TimeInterval(0.01 + Float(arc4random()) / Float(UInt32.max)) / 100
for (index, _) in attributedText.string.enumerated() {
DispatchQueue.main.asyncAfter(deadline: .now() + characterDelay * Double(index)) {
print("switcheroo value in TheViewController is now: \(TheViewController.shared.switcheroo)")
super.attributedText = attributedText.attributedSubstring(from: NSRange(location: 0, length: index+1))
}
}
}
}
如果您确定使用 ViewController
单例是正确的决定,可能的答案是您不是每次都使用该共享实例,而是在项目的某个时刻不小心调用了初始化程序 (可能 Xcode 通过接口自动完成。
要搜索整个项目,您可以使用 cmd + shift + F然后键入 TheViewController()
。应该只出现一次(共享实例)。请务必同时检查 TheViewController.init()
。任何时候你都会找到它。
如果问题仍然存在,也许可以尝试在 TheViewController
的 viewDidLoad
方法中将共享实例设置为 self
?
希望对您有所帮助!
我不建议仅仅为了某些共享状态或模型的目的而将视图控制器设为单例 属性。视图控制器有自己的生命周期模式(例如,从情节提要场景中实例化,在它们被关闭时释放,在再次呈现时重新创建,等等),并且您可能会因处理视图控制器的单独实例而产生问题).
相反,不要试图与标准视图控制器生命周期作斗争,而只是将此 属性 移动到一个单独的对象中,例如
final class StateManager {
static let shared = StateManager()
var switcheroo = 0
private init() { }
}
然后你的视图控制器可以使用它:
class ViewController: UIViewController {
...
func examineSwitcheroo() {
print(StateManager.shared.switcheroo)
}
func updateSwitcheroo(to value: Int) {
StateManager.shared.switcheroo = value
}
}
这样,您就可以享受这种共享状态,而不会在此过程中纠缠正常的视图控制器生命周期。
现在,这个单例的正确名称是什么,在我的例子中是 StateManager
,完全取决于这个共享的 属性 是什么。但是关于这个 switcheroo
对象的真正含义的信息不足,无法就此事提供更好的建议。
而且,可能不用说,关于是否真的应该对状态变量和模型对象使用单例,这是一个单独的问题,但这超出了这个问题的范围。
不要在视图控制器中管理应用程序的数据。 Cocoa 和 Cocoa Touch 框架使用 MVC 范式,其中 M 旨在代表模型,即应用程序的数据模型。任何需要保留的数据,或者超出视图控制器范围的相关数据,都应该在模型对象中存储和管理。如果您在创建视图控制器时为视图控制器提供了对模型的引用,那么您永远不必担心将数据从一个视图控制器传递到另一个视图控制器;相反,他们每个人都对模型进行操作,他们需要的任何数据都来自模型。
下面的视图控制器中变量 'switcheroo' 的值在我尝试通过单例访问它时始终相同。我正在尝试从一个自定义标签 class 访问它的值,该标签一个一个地打印标签的字符。设置标签后,我尝试在 Viewcontroller 单例中获取 switcheroo 的更新值。但是它总是 returns switcheroo 的初始值,而不是更新值(我可以在 viewcontroller 中追踪)。难道我做错了什么?
class TheViewController: UITableViewController, UIGestureRecognizerDelegate, UITabBarControllerDelegate {
static let shared = TheViewController()
var switcheroo = 0
... various operations that change the value of switcheroo...
}
class CustomLabel: UILabel {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override var attributedText: NSAttributedString? {
didSet {
DispatchQueue.main.async {
let characterDelay = TimeInterval(0.01 + Float(arc4random()) / Float(UInt32.max)) / 100
for (index, _) in attributedText.string.enumerated() {
DispatchQueue.main.asyncAfter(deadline: .now() + characterDelay * Double(index)) {
print("switcheroo value in TheViewController is now: \(TheViewController.shared.switcheroo)")
super.attributedText = attributedText.attributedSubstring(from: NSRange(location: 0, length: index+1))
}
}
}
}
如果您确定使用 ViewController
单例是正确的决定,可能的答案是您不是每次都使用该共享实例,而是在项目的某个时刻不小心调用了初始化程序 (可能 Xcode 通过接口自动完成。
要搜索整个项目,您可以使用 cmd + shift + F然后键入 TheViewController()
。应该只出现一次(共享实例)。请务必同时检查 TheViewController.init()
。任何时候你都会找到它。
如果问题仍然存在,也许可以尝试在 TheViewController
的 viewDidLoad
方法中将共享实例设置为 self
?
希望对您有所帮助!
我不建议仅仅为了某些共享状态或模型的目的而将视图控制器设为单例 属性。视图控制器有自己的生命周期模式(例如,从情节提要场景中实例化,在它们被关闭时释放,在再次呈现时重新创建,等等),并且您可能会因处理视图控制器的单独实例而产生问题).
相反,不要试图与标准视图控制器生命周期作斗争,而只是将此 属性 移动到一个单独的对象中,例如
final class StateManager {
static let shared = StateManager()
var switcheroo = 0
private init() { }
}
然后你的视图控制器可以使用它:
class ViewController: UIViewController {
...
func examineSwitcheroo() {
print(StateManager.shared.switcheroo)
}
func updateSwitcheroo(to value: Int) {
StateManager.shared.switcheroo = value
}
}
这样,您就可以享受这种共享状态,而不会在此过程中纠缠正常的视图控制器生命周期。
现在,这个单例的正确名称是什么,在我的例子中是 StateManager
,完全取决于这个共享的 属性 是什么。但是关于这个 switcheroo
对象的真正含义的信息不足,无法就此事提供更好的建议。
而且,可能不用说,关于是否真的应该对状态变量和模型对象使用单例,这是一个单独的问题,但这超出了这个问题的范围。
不要在视图控制器中管理应用程序的数据。 Cocoa 和 Cocoa Touch 框架使用 MVC 范式,其中 M 旨在代表模型,即应用程序的数据模型。任何需要保留的数据,或者超出视图控制器范围的相关数据,都应该在模型对象中存储和管理。如果您在创建视图控制器时为视图控制器提供了对模型的引用,那么您永远不必担心将数据从一个视图控制器传递到另一个视图控制器;相反,他们每个人都对模型进行操作,他们需要的任何数据都来自模型。