【问题标题】:NSFetchedResultsController unresolved identifier Swift 4NSFetchedResultsController 未解析的标识符 Swift 4
【发布时间】:2017-12-14 08:50:48
【问题描述】:

我收到了这个奇怪的“使用未解析的标识符”警告,即使我在上面的行中声明了 var。

这里发生了什么? 这是我的代码:

var fetchedResultsController: NSFetchedResultsController<Project> {

    if _fetchedResultsController != nil {
        return _fetchedResultsController
    }

    let fetchRequest: NSFetchRequest<Project> = Project.fetchRequest()

    fetchRequest.fetchBatchSize = 20

    let sortDescriptor = NSSortDescriptor(key: "name", ascending: false)

    fetchRequest.sortDescriptors = [sortDescriptor]

    let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: nil, cacheName: "Master")
    aFetchedResultsController.delegate = self
    _fetchedResultsController = aFetchedResultsController

    do {
        try _fetchedResultsController.performFetch()
    } catch {
         // Replace this implementation with code to handle the error appropriately.
         // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
         //println("Unresolved error \(error), \(error.userInfo)")
         abort()
    }

    return _fetchedResultsController!
}

这是来自 Apple 模板项目的代码,没有任何警告或错误:

 var fetchedResultsController: NSFetchedResultsController<Event> {

    if _fetchedResultsController != nil {
        return _fetchedResultsController!
    }

    let fetchRequest: NSFetchRequest<Event> = Event.fetchRequest()

    // Set the batch size to a suitable number.
    fetchRequest.fetchBatchSize = 20

    // Edit the sort key as appropriate.
    let sortDescriptor = NSSortDescriptor(key: "timestamp", ascending: false)

    fetchRequest.sortDescriptors = [sortDescriptor]

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: nil, cacheName: "Master")
    aFetchedResultsController.delegate = self
    _fetchedResultsController = aFetchedResultsController

    do {
        try _fetchedResultsController!.performFetch()
    } catch {
         // Replace this implementation with code to handle the error appropriately.
         // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
         let nserror = error as NSError
         fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
    }

    return _fetchedResultsController!
}    

我开始认为这可能与我创建的 CoreData 实体(类)(项目)有关。虽然它是一个具有一个属性(名称)的简单实体 - 模板项目也有一个具有一个属性(timeStamp)的实体(事件)。

CoreData 的“工具版本”设置为自动(XCode 9.0),“代码生成”设置为 Swift。

我注意到的另一件事是 XCode 有时无法识别我的实体(项目),我必须重新启动才能解决该问题。

XCode 9 是否被证明与 CoreData 存在问题?

【问题讨论】:

  • 请勿发图请发代码。最后,即使编译通过,您也将通过访问其 getter 中的属性进入无限循环。你有没有机会尝试实现惰性变量??
  • 我正要发布代码,但没有显示警告,因此无法正确显示我的问题。
  • 我会编辑问题。
  • 从您的第一个版本中的图像来看,“未声明的标识符”似乎是 _fetchedResultsController,这与 fetchedResultsController 不同 - 下划线被突出显示隐藏但与问题非常相关。您使用的代码是对 Apple 模板的轻微修改,是他们对 FRC 方法的 ObjectiveC 实现的遗留物。在 ObjectiveC 中,属性通常由实例变量支持,其名称默认为带有前导下划线的属性名称。
  • 您应该会发现Apple的模板也定义了var _fetchedResultsController,您可以将其复制到您的代码中以解决问题。

标签: ios core-data swift4 xcode9


【解决方案1】:

看起来您正在尝试创建 NSFetchedResultsController 的单例实例或尝试仅初始化一次 NSFetchedResultsController

问题:

直接在其getter中访问该属性将导致无限循环并且应用程序将崩溃。

解决方案:

您可能只需要lazy variable

lazy var fetchedResultsController : NSFetchedResultsController<Project> = {
    let localFetchedResultsController : NSFetchedResultsController< Project > = //initialize your fetched results controller
    return localFetchedResultsController
}()

这将确保 fetchedResultsController 仅被初始化一次并再次返回相同的实例 n 。除非你故意通过调用来改变实例本身

self.fetchedResultsController = //some_new_fetchedResultsController_instance

希望对你有所帮助

编辑 1:

你为什么不尝试一下

lazy var fetchedResultsController : NSFetchedResultsController<Project> = {
        let fetchRequest: NSFetchRequest<Project> = Project.fetchRequest()
        fetchRequest.fetchBatchSize = 20
        let sortDescriptor = NSSortDescriptor(key: "name", ascending: false)
        fetchRequest.sortDescriptors = [sortDescriptor]

        let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: nil, cacheName: "Master")
        aFetchedResultsController.delegate = self

        do {
            try aFetchedResultsController.performFetch()
        } catch {
            // Replace this implementation with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            //println("Unresolved error \(error), \(error.userInfo)")
            abort()
        }

        return aFetchedResultsController!
    }()

【讨论】:

  • 谢谢你,@Sandeep Bhandari。您的解决方案看起来比 Apple 代码中的解决方案更干净,我很可能会改成那样。 :)
  • @billysangster:如果有帮助,请考虑接受答案:)
猜你喜欢
  • 2016-04-29
  • 2014-08-10
  • 2015-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-13
  • 2016-11-28
  • 2015-05-25
相关资源
最近更新 更多