Ios CoreData返回空数据
coreData在不应该有空数据的情况下返回空数据,即使您卸载应用程序并重新安装并请求Сore data,context.fetch也会返回数据 获取Сore数据中的所有数据Ios CoreData返回空数据,ios,swift,core-data,nsfetchrequest,Ios,Swift,Core Data,Nsfetchrequest,coreData在不应该有空数据的情况下返回空数据,即使您卸载应用程序并重新安装并请求Сore data,context.fetch也会返回数据 获取Сore数据中的所有数据 func getMyLoadBook(){ words.removeAll() let appDelegate = UIApplication.shared.delegate as! AppDelegate let context = appDelegate.persistentContainer
func getMyLoadBook(){
words.removeAll()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequest:NSFetchRequest<Favorite> = Favorite.fetchRequest()
fetchRequest.returnsObjectsAsFaults = false
do {
let result = try! context.fetch(fetchRequest)
print(result)
if result.isEmpty {
emptyBookMark()
return
} else {
tableView.isHidden = false
}
for data in result as [NSManagedObject] {
if let _ = data.value(forKey: "word"){
let initData = Words(word: (data.value(forKey: "word") as? [String]) ?? [""], wordDesc: (data.value(forKey: "wordDesc") as? [String]) ?? nil, translation: (data.value(forKey: "translation") as? [String]) ?? [""], translDesc: (data.value(forKey: "translDesc") as? [String]) ?? nil)
words.append(initData)
}
}
}
tableView.reloadData()
}
static func deleteFromCoreData(data: [[String?]?]?){
coreDataResult(data: data, completion: { (result, taskObject, context) in
do {
let fetchedEntities = try context.fetch(result) as! [Favorite]
if let entityToDelete = fetchedEntities.first {
context.delete(entityToDelete)
}
do {
try context.save()
if let data = getDataFromContext(result:fetchedEntities){
Analytics.logEvent("RemovedFavorite", parameters: ["word": data.0, "translation": data.1])
YMMYandexMetrica.reportEvent("RemovedFavorite", parameters: ["word": data.0, "translation": data.1], onFailure: nil)
}
} catch {
print(error)
}
} catch { print(error) }
})
}
static func saveWithModelToCoreData(_ words: Words){
DispatchQueue.main.async {
coreDataResult(data: [words.word, words.translation], completion: { (result, taskObject, context) in
do {
let fetchedEntities = try context.fetch(result) as! [Favorite]
if let _ = fetchedEntities.first?.word {
print("the element already have in coreData")
} else {
taskObject?.setValue(words.word, forKey: "word")
taskObject?.setValue(words.translation, forKey: "translation")
taskObject?.setValue(words.descript, forKey: "wordDesc")
taskObject?.setValue(words.translDesc, forKey: "translDesc")
do {
try context.save()
} catch {
print(error)
}
}
} catch {
print(error)
}
})
}
}
//将数据添加到Сore数据中
func getMyLoadBook(){
words.removeAll()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequest:NSFetchRequest<Favorite> = Favorite.fetchRequest()
fetchRequest.returnsObjectsAsFaults = false
do {
let result = try! context.fetch(fetchRequest)
print(result)
if result.isEmpty {
emptyBookMark()
return
} else {
tableView.isHidden = false
}
for data in result as [NSManagedObject] {
if let _ = data.value(forKey: "word"){
let initData = Words(word: (data.value(forKey: "word") as? [String]) ?? [""], wordDesc: (data.value(forKey: "wordDesc") as? [String]) ?? nil, translation: (data.value(forKey: "translation") as? [String]) ?? [""], translDesc: (data.value(forKey: "translDesc") as? [String]) ?? nil)
words.append(initData)
}
}
}
tableView.reloadData()
}
static func deleteFromCoreData(data: [[String?]?]?){
coreDataResult(data: data, completion: { (result, taskObject, context) in
do {
let fetchedEntities = try context.fetch(result) as! [Favorite]
if let entityToDelete = fetchedEntities.first {
context.delete(entityToDelete)
}
do {
try context.save()
if let data = getDataFromContext(result:fetchedEntities){
Analytics.logEvent("RemovedFavorite", parameters: ["word": data.0, "translation": data.1])
YMMYandexMetrica.reportEvent("RemovedFavorite", parameters: ["word": data.0, "translation": data.1], onFailure: nil)
}
} catch {
print(error)
}
} catch { print(error) }
})
}
static func saveWithModelToCoreData(_ words: Words){
DispatchQueue.main.async {
coreDataResult(data: [words.word, words.translation], completion: { (result, taskObject, context) in
do {
let fetchedEntities = try context.fetch(result) as! [Favorite]
if let _ = fetchedEntities.first?.word {
print("the element already have in coreData")
} else {
taskObject?.setValue(words.word, forKey: "word")
taskObject?.setValue(words.translation, forKey: "translation")
taskObject?.setValue(words.descript, forKey: "wordDesc")
taskObject?.setValue(words.translDesc, forKey: "translDesc")
do {
try context.save()
} catch {
print(error)
}
}
} catch {
print(error)
}
})
}
}
这就是结果返回的结果
[<Favorite: 0x283478500> (entity: Favorite; id: 0x281306ee0 <x-coredata:///Favorite/t722DD7F9-8DD7-4AC4-AA20-02324AB1B08713> ; data: {
translDesc = nil;
translation = nil;
word = nil;
wordDesc = nil;
})
[(实体:收藏夹;id:0x281306ee0;数据:{
translDesc=零;
翻译=零;
字=零;
wordDesc=nil;
})
看起来您使用的是一个简单的核心数据设置,所有读写操作都是在viewContext的主线程上完成的。这个设置对于不希望进行大容量导入或拥有大量实体的简单应用程序来说是很好的。它应该会简化许多多线程问题,所以我有点困惑您为什么要这样做这样一个复杂的设置,包括回调和
DispatchQueue.main.async
,而一切都应该在主线程上运行。(也许您正在计划将来使用更复杂的设置?)
在任何情况下,这样做的后果之一是,对viewContext
的任何更改都将在应用的整个生命周期内出现在应用中,即使您没有调用save
。这是因为只有一个上下文-因此即使没有保存,它仍然会被更改
在方法coreDataResult
中创建一个空对象,然后在saveWithModelToCoreData
中使用值和保存的上下文对其进行设置,或者发现它已经存在,并且没有采取进一步的操作。如果coreDataResult
在后台上下文中返回,则该空对象将被禁用当背景上下文出现时会出现问题。问题是您正在写入viewContext
,因此上下文不会消失,对象会粘住
如果应用程序当时退出,你在下一次启动时将看不到它。但是如果在之后的任何时候调用save,那么空对象也将被保存
我建议不要创建对象,除非你已经知道你需要它们。我会重构,这样就有一个单一的函数来检查重复,然后创建和设置,或者什么都不做。事实上,我看不到这两个不同方法的价值。你试过了吗,替换了
let fetchRequest:NSFetchRequest=Favorite.fetchRequest()
与让fetchRequest:NSFetchRequest=Favorite.fetchRequest()
无关,但您使用了太多的问号。[[String?]?
非常有趣。例如,为什么saveWithModelToCoreData
中的参数是可选的?当您要调用此方法时,您确实想保存一些内容。@NSCoder我做了so@vadian选择的习惯如果我理解你是对的,你会说如果你重新安装了你的应用程序,然后从核心数据中获取数据,一个obJET返回给您(在您的问题中:id:0x281306ee0)虽然您以前没有存储此对象。但这是不可能的,因为如果您卸载应用程序,所有持久数据都将被删除。只需再次检查您是否删除了应用程序,如果错误仍然存在,请对存储到核心数据的所有内容进行注释,然后重试。我注意到了您的建议,问题出在guard let taskObject=NS中ManagedObject(实体:insertInto:context)作为?收藏夹else{return}