保存前修剪核心数据字段
Trimming core data field before saving
我想在将核心数据对象保存到上下文之前对其名称字段进行修整。我的想法是为此使用验证功能。以下实施有效:
@objc
public func validateName(_ value: AutoreleasingUnsafeMutablePointer<AnyObject?>) throws {
guard let trimmedValue = (value.pointee as? String)?.trimmingCharacters(in: .whitespaces) else {
return
}
if name != trimmedValue {
name = trimmedValue
}
}
如果没有if语句只在发生变化时设置name字段,core data会因为循环抛出异常
现在我要提问:
- 验证函数是执行此操作的最佳方法吗?
- 如果您有多个对象的字段必须被修剪,那么上面的代码会非常冗长。我试图创建一个带有 inout 变量值的函数 trimField,并移动了用于修剪、检查更改和设置 inout 变量的代码。但是当我从验证函数中调用它时,由于循环而抛出异常。所以似乎带有 inout 参数的函数确实将字段值设置为“脏”,即使它没有明确设置。还有其他选择吗?
验证之所以这样做,是因为正如您所发现的,只要您设置一个值,就会调用验证函数。要在验证时更改值,您需要使用 setPrimitiveValue(_:forKey:)
而不是像往常一样设置 name
来绕过验证。所以,setPrimitiveValue(trimmed, forKey: "name")
或类似的。
验证可能不是执行此操作的最佳时机。例如,您需要刷新显示对象数据的任何视图。还有一些其他选项。
一个是通过 didChangeValue
,像这样:
public override func didChangeValue(forKey key: String) {
if key == "name", let name = self.name {
let trimmedValue = nametrimmingCharacters(in: .whitespaces)
setPrimitiveValue(trimmedValue, forKey: "name")
}
super.willChangeValue(forKey: key)
}
您也可以使用 willSave
,并使用对象的 changedValues()
查看名称是否更改。
正确的做法——无论如何,就 Core Data 而言——是为 name
覆盖 setter。不幸的是,您需要关闭 Core Data 的自动代码生成才能做到这一点。我在这个答案中描述了这个过程:Using property observers on NSManaged vars
我想在将核心数据对象保存到上下文之前对其名称字段进行修整。我的想法是为此使用验证功能。以下实施有效:
@objc
public func validateName(_ value: AutoreleasingUnsafeMutablePointer<AnyObject?>) throws {
guard let trimmedValue = (value.pointee as? String)?.trimmingCharacters(in: .whitespaces) else {
return
}
if name != trimmedValue {
name = trimmedValue
}
}
如果没有if语句只在发生变化时设置name字段,core data会因为循环抛出异常
现在我要提问:
- 验证函数是执行此操作的最佳方法吗?
- 如果您有多个对象的字段必须被修剪,那么上面的代码会非常冗长。我试图创建一个带有 inout 变量值的函数 trimField,并移动了用于修剪、检查更改和设置 inout 变量的代码。但是当我从验证函数中调用它时,由于循环而抛出异常。所以似乎带有 inout 参数的函数确实将字段值设置为“脏”,即使它没有明确设置。还有其他选择吗?
验证之所以这样做,是因为正如您所发现的,只要您设置一个值,就会调用验证函数。要在验证时更改值,您需要使用 setPrimitiveValue(_:forKey:)
而不是像往常一样设置 name
来绕过验证。所以,setPrimitiveValue(trimmed, forKey: "name")
或类似的。
验证可能不是执行此操作的最佳时机。例如,您需要刷新显示对象数据的任何视图。还有一些其他选项。
一个是通过 didChangeValue
,像这样:
public override func didChangeValue(forKey key: String) {
if key == "name", let name = self.name {
let trimmedValue = nametrimmingCharacters(in: .whitespaces)
setPrimitiveValue(trimmedValue, forKey: "name")
}
super.willChangeValue(forKey: key)
}
您也可以使用 willSave
,并使用对象的 changedValues()
查看名称是否更改。
正确的做法——无论如何,就 Core Data 而言——是为 name
覆盖 setter。不幸的是,您需要关闭 Core Data 的自动代码生成才能做到这一点。我在这个答案中描述了这个过程:Using property observers on NSManaged vars