Swift:CoreData NSManagedObject的自定义设置器

时间:2014-09-08 03:56:48

标签: ios core-data swift setter

如何在Swift中为NSManagedObject实现自定义setter。我需要在设置NSMangedObject属性之前完成任务。

3 个答案:

答案 0 :(得分:7)

我的建议是使用KVC。也许不是最优雅的解决方案,但在概念上是KVC的逻辑应用。

观察属性的更改。在init(entity:insertIntoManagedObjectContext:)awakeFromFetch注册awakeFromInsert或更好的更改,并删除willTurnIntoFault中的观察者。

init(entity: NSEntityDescription!, insertIntoManagedObjectContext context: NSManagedObjectContext!) {
    super.init(entity: entity, insertIntoManagedObjectContext: context)
    addObserver(self, forKeyPath: "attribute", options: NSKeyValueObservingOptions.New | NSKeyValueObservingOptions.Old, context: nil)
}


override func observeValueForKeyPath(keyPath: String!, ofObject object: AnyObject!, change: NSDictionary!, context: CMutableVoidPointer) {
    if (keyPath == "attribute") {
           // do what you need to do
    }

}

针对Swift 3进行了更新:

init(entity: NSEntityDescription!, insertIntoManagedObjectContext context: NSManagedObjectContext!) {
    super.init(entity: entity, insertIntoManagedObjectContext: context)
    addObserver(self, forKeyPath: "attribute", options: [.old, .new], context: nil)
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if keyPath == "attribute" {
           // do what you need to do
    }
}

答案 1 :(得分:7)

如果不管理KVO订阅,甚至可以采用更简单的方法。可以通过覆盖didChangeValueForKey:这样简单地完成:

 override func didChangeValueForKey(key: String) {
    super.didChangeValueForKey(key)

    if key == "propertyName" {
        // do something now when propertyName changed
    }
}

答案 2 :(得分:0)

TL;DR

我建议覆盖 awakeFromInsert 而不是 init 因为它不需要 KVO 并且可以安全地访问对象属性。覆盖任何 init 方法是有风险且不必要的,因为对象及其属性可能尚未准备好可供访问(错误)。

说明

覆盖任何 init 方法是有风险且不必要的,因为对象及其属性可能尚未准备好被访问(错误)。但是,能够在开始接受数据之前准备 NSManagedObject 非常有用。也许我们想在将对象交给用户之前设置一些逻辑默认值或分配一些关系。在这些情况下,我们使用 awakeFromInsert。顾名思义,在通过插入调用创建 NSManagedObject 后立即调用此方法。

在设置任何值之前调用此方法,这是设置默认值、初始化瞬态属性以及执行我们通常在 init 方法中处理的其他任务的绝佳机会。该方法在对象的整个生命周期中只被调用一次。它不会在应用程序的下一次执行时被调用,也不会在从持久存储中读入对象时被调用。因此,我们无需担心覆盖之前设置的值。当我们重写这个方法时,我们应该确保在我们的实现开始时调用 super.awakeFromInsert() 以允许 NSManagedObject 在我们开始我们的代码之前完成它需要的任何事情。

Xcode 代码段中的便捷 ObjC 快捷方式 (Xcode 12)

Xcode Snippet for awakeFromInsert1

注意:为此手动添加您自己的 Swift 代码段非常容易。您也可以尝试一些 GH 存储库。例如对于Swift 4 snippets