Swift中variables值变化时执行方法

当variables值改变时,我需要执行一个函数。

我有一个singleton类包含一个名为labelChange的共享variables。 这个variables的值来自另一个叫做Model类。 我有两个VC类,其中一个有一个button和一个标签,第二个只有一个button。

当按下第一个VC类中的button时,我正在用这个func更新标签:

 func updateLabel(){ self.label.text = SharingManager.sharedInstance.labelChange } 

但是我想在labelChange的值改变时调用相同的方法。 所以在button点击我只会更新labelChange值,当这个事情发生时,我想用labelChange的新值更新标签。 另外在第二个VC中,我能够更新labelChange值,但是当这个值被改变时,我无法更新标签。

也许属性是解决scheme,但任何人都可以告诉我如何做到这一点。

第二次编辑:

单身职业:

 class SharingManager { func updateLabel() { println(labelChange) ViewController().label.text = SharingManager.sharedInstance.labelChange } var labelChange: String = Model().callElements() { willSet { updateLabel() } } static let sharedInstance = SharingManager() } 

首先VC:

 class ViewController: UIViewController { @IBOutlet weak var label: UILabel! @IBAction func Button(sender: UIButton) { SViewController().updateMessageAndDismiss() } } 

第二个VC:

 func updateMessageAndDismiss() { SharingManager.sharedInstance.labelChange = modelFromS.callElements() self.dismissViewControllerAnimated(true, completion: nil) } @IBAction func b2(sender: UIButton) { updateMessageAndDismiss() } 

我做了一些改进,但是我需要从单例中的第一个VC类引用一个标签。 所以我会更新单身人士VC的标签。

当我打印labelChange的价值正在更新,一切都很好。 但是,当我尝试更新单身人士的标签上的值我收到一个错误:

意外地发现零,而解包一个可选的值

并且错误指向单例类的第四行。

你可以简单地使用一个属性observer作为variableslabelChange ,然后调用你想要在didSet调用的函数(或者如果你想在调用它之前调用willSet ):

 class SharingManager { var labelChange: String = Model().callElements() { didSet { updateLable() } } static let sharedInstance = SharingManager() } 

这在Property Observers中有解释。

我不确定为什么当你尝试时这样做不起作用,但是如果你遇到麻烦,因为你试图调用的函数( updateLable )在不同的类中,你可以在SharingManager类中添加一个variables来存储调用didSet时调用的函数,在这种情况下您将设置updateLable

编辑:

所以如果你想从ViewController中编辑一个标签,你需要在ViewController类中有updateLable()函数来更新标签,但是将这个函数存储在singleton类中,这样它就可以知道要调用哪个函数:

 class SharingManager { static let sharedInstance = SharingManager() var updateLable: (() -> Void)? var labelChange: String = Model().callElements() { didSet { updateLable?() } } } 

然后将其设置为你想调用函数的类,比如(假设updateLable是你要调用的函数):

 SharingManager.sharedInstance.updateLable = updateLable 

当然,你会想确保负责该函数的视图控制器仍然存在,所以单例类可以调​​用该函数。

如果您需要根据哪个视图控制器可见,调用不同的函数,则可能需要考虑键值观察 ,以便在某些variables的值发生更改时收到通知。

此外,你永远不想初始化一个视图控制器,然后立即设置视图控制器的IBOutlets,因为IBOutlets不会被初始化,直到它的视图实际上被加载。 您需要以某种方式使用现有的视图控制器对象。

希望这可以帮助。

还有另外一种方法,使用RxSwift:

  1. 将RxSwift和RxCocoa窗格添加到您的项目中

  2. 修改您的SharingManager

     import RxSwift class SharingManager { static let sharedInstance = SharingManager() private let _labelUpdate = PublishSubject<String>() let onUpdateLabel: Observable<String>? // any object can subscribe to text change using this observable // call this method whenever you need to change text func triggerLabelUpdate(newValue: String) { _labelUpdate.onNext(newValue) } init() { onUpdateLabel = _labelUpdate.shareReplay(1) } } 
  3. 在您的ViewController中,您可以通过两种方式订阅值更新:

    一个。 订阅更新,并手动更改标签文本

     // add this ivar somewhere in ViewController let disposeBag: DisposeBag() // put this somewhere in viewDidLoad SharingManager.sharedInstance.onUpdateLabel? .observeOn(MainScheduler.instance) // make sure we're on main thread .subscribeNext { [weak self] newValue in // do whatever you need with this string here, like: // self?.myLabel.text = newValue } .addDisposableTo(disposeBag) // for resource management 

    湾 将更新直接绑定到UILabel

     // add this ivar somewhere in ViewController let disposeBag: DisposeBag() // put this somewhere in viewDidLoad SharingManager.sharedInstance.onUpdateLabel? .distinctUntilChanged() // only if value has been changed since previous value .observeOn(MainScheduler.instance) // do in main thread .bindTo(myLabel.rx_text) // will setText: for that label when value changed .addDisposableTo(disposeBag) // for resource management 

别忘了在ViewController中import RxCocoa

触发事件只是打电话

 SharingManager.sharedInstance.triggerLabelUpdate("whatever string here") 

这里你可以find示例项目。 只要做pod update并运行工作区文件。

 var item = "initial value" { didSet { //called when item changes print("changed") } willSet { print("about to change") } } item = "p" 

苹果提供这些属性声明types: –

1.计算属性: –

除了存储的属性,类,结构和枚举可以定义计算的属性,而实际上并不存储值。 相反,它们提供了一个getter和一个可选的setter来间接检索和设置其他属性和值。

 var otherBool:Bool = false public var enable:Bool { get{ print("i can do editional work when setter set value ") return self.enable } set(newValue){ print("i can do editional work when setter set value ") self.otherBool = newValue } } 

2.只读计算属性: –

具有getter但没有setter的计算属性被称为只读计算属性。 只读计算属性总是返回一个值,可以通过点语法访问,但不能设置为不同的值。

 var volume: Double { return volume } 

3.物业观察员: –

您可以select在属性中定义这些观察者中的一个或两个:

将在存储值之前调用willSet
在新值被存储之后立即调用didSet

 public var totalSteps: Int = 0 { willSet(newTotalSteps) { print("About to set totalSteps to \(newTotalSteps)") } didSet { if totalSteps > oldValue { print("Added \(totalSteps - oldValue) steps") } } } 

注意: – 更多信息继续专业链接 https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html