核心数据 - NSManagedObject 返回 nil

Posted

技术标签:

【中文标题】核心数据 - NSManagedObject 返回 nil【英文标题】:Core Data - NSManagedObject returning nil 【发布时间】:2016-04-29 10:07:58 【问题描述】:

我写了两个单独的函数fetchRecordsdisplayRecords 写在Appdelegate 类中。 fetchRecords 函数将从实体中获取所有记录,它工作正常。displayRecords 函数接受来自fetchRecords 函数的返回值并一一打印所有记录。 我有一个视图控制器,它调用这两个函数来完成所需的任务。我的问题是displayRecords 中的result.count 显示获取的记录中可用的记录总数。在打印记录时,值为零。

override func viewDidLoad() 
super.viewDidLoad()
    let fetchedRecords = AppDelegate().fetchRecords(fromEntity: "Dashboard")
    AppDelegate().displayRecords(fromFetchedRecords: fetchedRecords)   

这是用 AppDelegate 类编写的 fetchRecordsdisplayRecords 函数

  func fetchRecords(fromEntity entity:String) -> Array<AnyObject> 
    var fetchedResult:Array<AnyObject> = []
    let fetchRequest = NSFetchRequest()
    let entityDescription = NSEntityDescription.entityForName(entity, inManagedObjectContext: self.managedObjectContext)!
    fetchRequest.entity = entityDescription
    do
        fetchedResult = try self.managedObjectContext.executeFetchRequest(fetchRequest)              
    catch
        let fetchError = error as NSError?
        print(fetchError!)
    
   return fetchedResult


func displayRecords(fromFetchedRecords result:Array<AnyObject>) 
    print("Total records:\(result.count)")
    if (result.count > 0) 
        for data in result 
        let dashboard = data as! NSManagedObject
        print("Value: \(dashboard.valueForKey("count"))")
        
    

在此处添加我的数据模型

我也会分享数据插入代码。

func saveDashBoardData(dictionary: Dictionary<String, String>) 
    print(NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask))

    //Create Manage Object
    let entityDescription: NSEntityDescription = NSEntityDescription.entityForName("Dashboard", inManagedObjectContext: self.managedObjectContext)!
    for data in dictionary 
        let dashboardObject = Dashboard(entity: entityDescription,insertIntoManagedObjectContext: self.managedObjectContext)
        dashboardObject.type  = data.0
        dashboardObject.count = data.1
        do 
            try self.managedObjectContext.save()
            print("Data saved succesfully")
        
        catch 
            print(error)
        
    

【问题讨论】:

你能告诉我你项目中的核心数据模型吗@sindhu ja 我已经分享了问题中的数据模型。请找到它 我听不懂你想说什么@vadian @sindhu ja:你能在 let dashboard = data as 处设置一个断点吗! NSManagedObject 并确认仪表板对象是否为零?我想它不会是,如果它是 nil,它本身就会崩溃。这意味着您的获取请求正在正确地感染仪表板对象,但可能是仪表板对象在计数中没有属性值:) 所以您可以做的是发布将仪表板对象插入核心数据的代码 @SandeepBhandari 插入工作正常,我可以看到数据库中的数据。无论如何我会分享代码。 【参考方案1】:

问题在于AppDelegate() 总是创建一个与应用程序的“硬编码”委托实例不同的类的新实例。

你必须写

let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let fetchedRecords = appDelegate.fetchRecords(fromEntity: "Dashboard")
appDelegate.displayRecords(fromFetchedRecords: fetchedRecords)

由于您已经创建了 NSManagedObject 的自定义子类,因此请将其用作类型而不是 NSManagedObject 或者更糟糕的是未指定的 AnyObject。它使许多事情变得更容易:

func fetchRecords(fromEntity entity:String) -> [Dashboard] 
  let fetchRequest = NSFetchRequest()
  let entityDescription = NSEntityDescription.entityForName(entity, inManagedObjectContext: self.managedObjectContext)!
  fetchRequest.entity = entityDescription
  do 
     return try self.managedObjectContext.executeFetchRequest(fetchRequest) as! [Dashboard]              
   catch let fetchError as NSError 
     print(fetchError!)
  
  return [Dashboard]()


func displayRecords(fromFetchedRecords result:[Dashboard]) 
    print("Total records:\(result.count)")

    for dashboard in result  // the check for empty is not needed
       print("Value: \(dashboard.count)")
    

【讨论】:

谢谢@vadian。为AppDelegate 创建实例解决了这个问题。 对 AppDelegate 使用紧密耦合是不好的,并且会给您带来更多的麻烦。您最好遵循最近在Core Data Programming Guide 中列出的设计,而不是模板中的内容。【参考方案2】:

试试这个..

let dashboard = Dashboard as! NSManagedObject

print("Value: \(dashboard.count)")

我认为它可能会起作用。因为您已将 ManagedObject 作为数据。最好把它当作一种仪表板。这样您就可以通过dashboardObj.count ..访问count ..

希望您为实体创建了 Core Data NSManagedSubclass。

希望对你有帮助..

【讨论】:

是的,我已经为该实体创建了 NSManagedSubclass。我尝试了你的建议,但它也不起作用。【参考方案3】:

从您的 coredata 模型创建 Dashboard 的 NSManagedObject 子类。

func displayRecords(fromFetchedRecords result:Array<AnyObject>) 

    print("Total records:\(result.count)")
    if (result.count > 0) 
        for data in result 
        let dashboard = data as! Dashboard
        print("Value: \(dashboard.valueForKey("count"))")
        
    

这里的关键变化是让仪表板=数据为!仪表盘。 仪表板是您需要在核心数据模型帮助下创建的托管对象子类。

【讨论】:

谢谢@Dovakin。我们使用了您的建议并为AppDelegate 创建实例解决了这个问题。

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

核心数据 NSManagedObject - ObservedObjects 未更新

使用 XCode 7 和 Swift 向下转换的核心数据 NSManagedObject

仅返回和导出 NSManagedObject 的值

仅返回并导出NSManagedObject的值

从众多实体中恢复一个获取的实体——核心数据

NSManagedObject 保存在核心数据中但属性错误