NSFetchedResultsController - 在展开可选值时意外发现 nil
Posted
技术标签:
【中文标题】NSFetchedResultsController - 在展开可选值时意外发现 nil【英文标题】:NSFetchedResultsController - unexpectedly found nil while unwrapping an Optional value 【发布时间】:2015-10-09 15:09:54 【问题描述】:我正在使用NSFetchedResultsController
来填充我的 TableView。我有一个实体“HubProfile”,其属性为:“Name”和“HubID”
问题: NSFetchedResultsController
即将到来 nil
。奇怪的是,当我在viewDidLoad
和cellForRowIndexPath
方法中打印fetchedResultsController
时——它给出了一个值。但是在numberOfRowsInSection
方法中,fetchedResultsController
是nil
并且应用程序崩溃了。
此外,数据已经保存在 CoreData 中。我在 SQLite 浏览器中看到过——所以有数据要加载
似乎无法弄清楚为什么。
下面是我的代码:
class StudentsController: UIViewController, UITableViewDataSource, UITableViewDelegate, NSFetchedResultsControllerDelegate
let managedContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
var fetchedResultsController: NSFetchedResultsController!
override func viewDidLoad()
super.viewDidLoad()
//FETCH REQUESTS
let fetchRequest = NSFetchRequest(entityName: "HubProfile")
let sortDescriptor = NSSortDescriptor(key: "name", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
fetchRequest.predicate = NSPredicate(format: "hubID = %@", hubID!)
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedContext, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController.delegate = self
do
try! fetchedResultsController.performFetch()
print(fetchedResultsController) //THIS IS NOT NIL
//TABLEVIEWDATASOURCE PROTOCOL:
func numberOfSectionsInTableView(tableView: UITableView) -> Int
return 1
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
print(fetchedResultsController) // THIS IS NIL
let sectionInfo = fetchedResultsController.sections![section] as NSFetchedResultsSectionInfo
return sectionInfo.numberOfObjects
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! StudentsCell!
print(fetchedResultsController) //THIS is NOT Nil
let hubProfile = fetchedResultsController.objectAtIndexPath(indexPath) as! HubProfile
cell.nameLabel?.text = hubProfile.name
return cell
【问题讨论】:
所以表视图试图在任何数据出现之前访问“fetchedResultsController”。所以你可以做的是首先检查它是否为空,然后在viewdidload中获取后放置一个tableview.reload。当获取数据时,它将重新加载 tableview。 并且每当你使用可选值时,尝试安全地解包,然后你就不会得到这个错误。 尝试了重新加载数据..没有工作..正如我在 viewDidLoad 中所说..我已经放了一个 print(fetchedResultsController)..工作正常..问题只在 numberOfRowsInSection方法。 通过以下所有更改使viewDidLoad
成为可选应该可以解决问题,出于好奇,我想查看tableView:numberOfRowsInSection:
调用的回溯,其中fetchedResultsController
为nil,以及无论是在 viewDidLoad
之前还是之后调用。
我不确定我是否理解正确..我将fetchedResultsController
声明设为可选..它仍然崩溃...因为“__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray'” ...基本上fetchedResultsController
为零..
【参考方案1】:
tableView 可能在 fetchResultsController 有机会加载之前已经加载。因此,在执行 Fetch() 后立即重新加载表:
do
try! fetchedResultsController.performFetch()
tableView.reloadData()
print(fetchedResultsController) //THIS IS NOT NIL
然后在您的 tableView 函数中检查 fetchedResultsController 是否为 nil,如果是,则给它一些其他值(在本例中为 0),当获取完成后重新加载表时,该函数将从您的fetchResultsController(当它是 != nil 时):
override func numberOfSections(in tableView: UITableView) -> Int
return fetchedResultsController.sections?.count ?? 0
【讨论】:
以上是关于NSFetchedResultsController - 在展开可选值时意外发现 nil的主要内容,如果未能解决你的问题,请参考以下文章