核心数据值返回 Nil

Posted

技术标签:

【中文标题】核心数据值返回 Nil【英文标题】:Core Data Value returns Nil 【发布时间】:2017-05-01 20:05:31 【问题描述】:

您好,我一直在使用核心数据来存储和检索核心数据中的一些值(仅限字符串)。这是我存储值的方式。

功能:

public func saveStringValue(forKey: String, value: String) -> Bool
    var saved = false
    if self.entityName != nil && self.appDelegate != nil
        let context = appDelegate?.persistentContainer.viewContext
        if context != nil
            let entity = NSEntityDescription.entity(forEntityName: self.entityName!, in: context!)
            let entityHandle = NSManagedObject(entity: entity!, insertInto: context!)
            entityHandle.setValue(value, forKey: forKey)
            do
                try context?.save()
                saved = true
            catch let error as NSError
                saved = false
                print("Error : \(error)")
            
        
    

    return saved 

我是这样称呼它的

let historyManager = HistoryManager(entity: "SearchHistory")
        let titleInserted = historyManager.saveStringValue(forKey: "title", value: book.title!)
        if(titleInserted == true)
        
            print("Title Inserted to Entity")
        

        if let image = book.imageUrl
            let imageInserted = historyManager.saveStringValue(forKey: "image", value: image)
            if imageInserted == true
                print("Image Url Inserted to Entity")
            
        

我可以在控制台中看到打印出来的

    标题插入到实体中 图像插入到实体中

这是从核心数据存储中检索值的代码

public func fetchAll() -> [Book]
    var books = [Book]()
    let context = self.appDelegate?.persistentContainer.viewContext
    let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: self.entityName!)
    //let fetchRequest: NSFetchRequest<SearchHistory> = SearchHistory.fetchRequest()

    do
        let fetchedBooks = try context?.fetch(fetchRequest)

        for aBook in fetchedBooks!
            if let title = aBook.value(forKey: "title")
                let book = Book(title: title as! String)
                if let im = aBook.value(forKey: "image")

                    book.imageUrl = im as! String
                    print("ImageUrl : \(im) : ")
                
                else
                    print("No Value for key : image")
                
                books.append(book)
            


        
    
    catch let error as NSError
        print("Fetch Error: \(error.localizedDescription)")
    
    print("Books : \(books.count)")
    return books

但是当我运行代码来检索书 imageUrl 它返回 nil 并打印

    键没有值:图像 它检索标题但不检索 imageUrl。 你能帮我解决这个问题或指出正确的方向吗?请务必发布我遇到此问题的原因以及如何解决它。谢谢。

【问题讨论】:

【参考方案1】:

您的问题是您的saveStringValue 每次调用它时都会创建一个新的NSManagedObject 实例。

第一次调用saveStringValue 时,您将创建一个SearchHistory 对象,该对象具有title 但没有image。第二次调用它时,您将创建另一个具有image 值但没有titleSearchHistory 对象。

在我看来,您的saveStringValue 函数是不必要的。假设您的代码基于在 Xcode 中单击“使用核心数据”产生的模板,您将有一个可用的 SearchHistory 类,您可以使用如下内容:

let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext

let newHistory = SearchHistory(context: context)

newHistory.title = book.title
newHistory.image = book.imageUrl

appDelegate.saveContext()

【讨论】:

为什么要写 let newHistory = SearchHistory(context: Context) 没有类SearchHistory。 Xcode 会自动为您的核心数据实体创建类,除非您在核心数据模型中关闭此选项。

以上是关于核心数据值返回 Nil的主要内容,如果未能解决你的问题,请参考以下文章

多线程核心数据有时会返回 nil 属性

核心数据查询值“不是零”不返回值等于 0 的对象

核心数据 NSPersistentStoreCoordinator 的 +metadataForPersistentStoreOfType:URL:error: 有时返回 nil

核心数据 NSEntityDescription.entityForName 返回 nil,但 managedObjectModel.entities 列出了实体

核心数据 - NSManagedObjectContext 在 Master-Detail 应用程序中返回 nil

从 PHAsset 中提取元数据返回意外的 nil 值