如何解决核心数据:如何最好地反复检查唯一性?保存上下文?取数?
更新:我根据建议查找了核心数据验证(在 managedobhects 上的validateForInsert()),但不知何故它没有发现唯一性约束违规。我不知道为什么,因为它看起来应该很简单。我在父类和子上下文(在每个上下文中的相应对象上)的超类 managedobject 类型和特定实体类型上都尝试了它,但没有任何效果。虽然,到目前为止我只在 UIManagedDocument 上尝试过。验证听起来是一个更好的选择,但我很沮丧,我无法让它发挥作用,也不知道为什么。
——
不久前我写了一个函数来为核心数据实体创建默认名称。我几乎不知道它让我陷入了多大的麻烦……如果您有兴趣,可以在另一个(已解决的)问题中找到 func 的第一次迭代(您不必阅读该问题来理解这个问题):
第一次迭代工作正常。但是,它没有考虑现有默认名称的数量之间是否存在差距。例如,如果数据库中同时存在 name、name1 和 name3,则会创建 name3 的重复,并且不满足名称必须唯一的地方。
所以为了解决这个问题,我想我应该添加一个 while 循环来检查新创建的名称的唯一性,并在每个循环中将计数增加 1,直到它确实是唯一的。这不会总是填补空白,但我只是希望名称是唯一的。我将在下面提供代码,但首先,我遇到的问题是它的行为“时髦”。有时,名称不应该是 nil(没有发现错误)或不正确的名称已经存在。所以我的问题是我的代码有什么问题?或者我可以做些什么来找出问题所在?或者,除了通过保存上下文检查唯一性错误之外,还有没有更好的方法来检查唯一性? (也许应该只获取并计算结果?)我是否错误地处理了这个默认名称函数?我将不胜感激任何意见和讨论。
这是我的代码。设置是一个 UIManagedDocument,它自动提供两个上下文,一个子项和一个父项。父母是背景。我现在只使用孩子进行编辑,但我确实设置并检查了两者是否抛出唯一性错误。我还为属性设置了唯一性约束。(为简单起见,我省略了我定义的错误类型以及与之相关的错误类型转换。)
func checkUniqueness()throws {
var mergeError: Error? = nil
do{
try childContext.save()
childContext.parent!.performAndWait{
do{
childContext.parent!.save()
}catch{
mergeError = error
print(“parent error”)
}
}catch{
mergeError = error
print(“child error”)
}
if mergeError != nil{
if (mergeError! as NSError).code == 133021 && (mergeError! as NSError).domain == NSCocoaErrorDomain{
throw someUniquenessErrorIDefined
}else{
throw someDataErrorIDefined
}
}
}
//can throw an error indicating func Failed and name is set to nil
func setDefaultName<T>(entity:T,defaultString: String,attribute: String) throws {
try? context.save()
//initial values
var name = defaultString
var count = 0
var someError: Error? = nil
//fetch the count
let type = T.self
let fetchRequest = NSFetchRequest<NSNumber>(entityName: “\(type)”)
let pred = nspredicate(format: “%K CONTAINS[cd] %@",attribute,defaultString)
fetchRequest.predicate = pred
fetchRequest.resultType = .countResultType
do {
let result = try context.fetch(fetchRequest)
count = result.first!.intValue
}catch{
throw someDataErrorIDefined
}
//
//loop to find unique value
repeat{
do{
if count != 0{
name = defaultString + String(count)
}
(entity as! NSManagedobject).setValue(name,forKey: attribute)
count += 1
try checkUniqueness()
someError = nil
}catch{
someError = error
}
} while someError == someUniquenessErrorIDefined
if someError == someDataErrorIDefined{
(entity as! NSManagedobject).setValue(nil,forKey: attribute)
throw someError
}
}
我应该补充一点,在我重新启动 Xcode 后这些奇怪的行为消失了,而且我无法重现它们,但我只是担心它们会再次出现。也许我根本不应该以这种方式检查唯一性?我刚刚读到唯一性约束是确保唯一性的更高效的方式,但我不确定它们是否应该像这样使用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。