swift 2核心数据谓词不一致
swift 2 core data predicate inconsistent
我对核心数据的谓词方法有疑问,因为它返回的结果似乎有些不一致。我有一个从网络 API 填充的 "Users" 实体,而不是删除所有条目然后下载和添加用户,我更喜欢将所有用户的标志 "isModified" 设置为 false ,然后通过 API 下载用户,并根据他们是否在商店中更新或添加用户,当他们 added/updated 时设置 "isModified" 标志。最后,代码会删除所有未设置 "isModified" 标志的用户。我这样做是因为如果网络 API 不可用,我不会失去所有用户,应用程序可以继续工作。
我遇到的问题是,删除未设置 "isModified" 标志的用户的方法是删除已更新的用户!
方法如下:
func deleteUsersNotUpdated() -> Bool {
// default result
var result = false
// setup the fetch request
let fetchRequest = NSFetchRequest(entityName: "Users")
// set a predicate that filters only records with updated set to false
fetchRequest.predicate = NSPredicate(format: "isModified == %@", false)
do {
let fetchResults = try self.managedObjectContext.executeFetchRequest(fetchRequest) as! [NSManagedObject]
for user in fetchResults {
print("Deleting \(user)")
self.managedObjectContext.deleteObject(user)
try self.managedObjectContext.save()
}
result = true
} catch let error as NSError {
print("\(error)")
}
return result
}
该方法大部分有效,但会间歇性地无缘无故地删除用户,即即使它设置了 "isModified" 标志,例如这是该行的输出:print("Deleting (user)")
Deleting <NSManagedObject: 0x7b6d6ec0> (entity: Users; id: 0x7b64abd0 <x-coredata://1A7606EB-3539-4E85-BE1C-15C722AD7125/Users/p14> ; data: {
created = "2016-01-17 16:54:21 +0000";
familyName = Doe;
givenName = John;
isModified = 1;
pin = 3932;
type = STAFF;
})
如您所见,"isModified" 标志已明确设置,但谓词应该 select 仅记录已重置标志 (false) 的记录。
上面的方法是我创建的 class 的一部分,它基本上是用户实体的 CRUD class。
在这里挠我的头!
如果需要,我可以提供其余代码。
使用布尔文字而不是 对象 占位符 %@
作为 布尔值 值
NSPredicate(format: "isModified == FALSE")
并且不要在repeat循环的每次迭代中调用context.save()
,在repeat循环之后调用一次。
我认为您的代码看起来非常好(尽管您应该保存在循环之外)。 Swift 布尔值在大多数情况下会自动转换为 NSNumber
并返回。这个谓词有很多有效的写法。
想到的唯一可能的解释是另一个class正在使用相同的托管对象上下文修改获取的对象。如果您有一个上下文应用程序,这是一个可以想象的场景。
避免这种情况的标准方法是在后台上下文中进行更改。
我对核心数据的谓词方法有疑问,因为它返回的结果似乎有些不一致。我有一个从网络 API 填充的 "Users" 实体,而不是删除所有条目然后下载和添加用户,我更喜欢将所有用户的标志 "isModified" 设置为 false ,然后通过 API 下载用户,并根据他们是否在商店中更新或添加用户,当他们 added/updated 时设置 "isModified" 标志。最后,代码会删除所有未设置 "isModified" 标志的用户。我这样做是因为如果网络 API 不可用,我不会失去所有用户,应用程序可以继续工作。
我遇到的问题是,删除未设置 "isModified" 标志的用户的方法是删除已更新的用户!
方法如下:
func deleteUsersNotUpdated() -> Bool {
// default result
var result = false
// setup the fetch request
let fetchRequest = NSFetchRequest(entityName: "Users")
// set a predicate that filters only records with updated set to false
fetchRequest.predicate = NSPredicate(format: "isModified == %@", false)
do {
let fetchResults = try self.managedObjectContext.executeFetchRequest(fetchRequest) as! [NSManagedObject]
for user in fetchResults {
print("Deleting \(user)")
self.managedObjectContext.deleteObject(user)
try self.managedObjectContext.save()
}
result = true
} catch let error as NSError {
print("\(error)")
}
return result
}
该方法大部分有效,但会间歇性地无缘无故地删除用户,即即使它设置了 "isModified" 标志,例如这是该行的输出:print("Deleting (user)")
Deleting <NSManagedObject: 0x7b6d6ec0> (entity: Users; id: 0x7b64abd0 <x-coredata://1A7606EB-3539-4E85-BE1C-15C722AD7125/Users/p14> ; data: {
created = "2016-01-17 16:54:21 +0000";
familyName = Doe;
givenName = John;
isModified = 1;
pin = 3932;
type = STAFF;
})
如您所见,"isModified" 标志已明确设置,但谓词应该 select 仅记录已重置标志 (false) 的记录。
上面的方法是我创建的 class 的一部分,它基本上是用户实体的 CRUD class。
在这里挠我的头! 如果需要,我可以提供其余代码。
使用布尔文字而不是 对象 占位符 %@
作为 布尔值 值
NSPredicate(format: "isModified == FALSE")
并且不要在repeat循环的每次迭代中调用context.save()
,在repeat循环之后调用一次。
我认为您的代码看起来非常好(尽管您应该保存在循环之外)。 Swift 布尔值在大多数情况下会自动转换为 NSNumber
并返回。这个谓词有很多有效的写法。
想到的唯一可能的解释是另一个class正在使用相同的托管对象上下文修改获取的对象。如果您有一个上下文应用程序,这是一个可以想象的场景。
避免这种情况的标准方法是在后台上下文中进行更改。