首页 > 解决方案 > 如何使用属性观察器更新在其他控制器中具有相同属性的 swift NSObject 模型?

问题描述

我正在阅读 Apple 文档和一些教程,从中了解到我们可以设置观察者,如果对象被修改,它将被调用。但我心中几乎没有疑问。

下面是一个关于属性更改通知模型的摘要:

在此处输入图像描述

假设有 3 个视图控制器,它们显示Foo模型列表。Foo模型具有称为id和的属性title。我的问题是,是否可以在其他控制器中通知模型已修改,例如Fooid 10 个。是否只有在 3 个控制器之间共享相同的模型实例时才有可能,或者尽管实例不同,但我们可以实现它?

我正在寻找一个具体的解决方案,其中用户喜欢一个屏幕中的提要(类似于 Facebook),并且如果具有相同 id 的提要在其他控制器中,则应通知该控制器该提要已修改,刷新其 UI。我附上了一张图片以获得清晰的想法。

在此处输入图像描述

我不希望使用委托或通知模式,因为它可能会造成混乱,而观察者模式将是更合适的解决方案。

标签: iosswiftuiviewcontrollerkey-value-observingnsobject

解决方案


这是一个如何实现这一目标的示例。

饲料型号:

class Feed: NSObject {
    var id: String
    @objc dynamic var isLiked = false

    init(id: String) {
        self.id = id
    }
}

任何你想观察的属性,标记它@objc dynamic,即isLikedFeed模型中。

class ListVC: UIViewController {
    let feed = Feed(id: "1")
    var observer: NSKeyValueObservation?

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    @IBAction func openDetailVC(_ sender: UIButton) {
        if let detailVC = self.storyboard?.instantiateViewController(withIdentifier: "DetailVC") as? DetailVC {
            self.observer = detailVC.feed.observe(\.isLiked, options: [.new], changeHandler: { (feed, change) in
                if let newValue = change.newValue {
                    print(newValue)
                    //Reload the UI here...
                }
            })
            self.navigationController?.pushViewController(detailVC, animated: true)
        }
    }
}

接下来有一个ListVC具有feed属性的。

在. observer_ feed_ 在ieviewDidLoad()中指定要观察的属性。每次属性发生变化时都会调用 in 观察者。feedisLikedclosureisLiked

现在,DetailVC会的。

class DetailVC: UIViewController {
    let feed = Feed(id: "1")

    @IBAction func likeButtonPressed(_ sender: UIButton) {
        self.feed.isLiked = !self.feed.isLiked
    }
}

在上面的代码中,每当按下时,我都会更改isLiked属性的值。feedlikeButton


推荐阅读