我一直收到这个错误:
2017-10-18 22:57:52.401421 + 0300费用管理器[4213:133067] *由于未捕获的异常'NSRangeException'而终止应用程序,原因:'* - [__ NSArray0 objectAtIndex:] :索引0超出空NSArray'
的边界
但我不知道我做错了什么。当 numberOfSections 1 并且它们没有按日期排序时, tableView 可以正常工作,但是当我尝试每天执行某些部分时,它应用程序启动时崩溃。
func userBudgetCount(_ section: Int) -> Int {
return fetchedResultsController.sections![section].numberOfObjects
}
func getUserBudgetAtIndexPath(indexPath : IndexPath) -> Budget {
return fetchedResultsController.object(at: indexPath) as Budget
}
override func viewDidLoad() {
super.viewDidLoad()
self.hideKeyboard()
tableView.delegate = self
tableView.dataSource = self
self.tableView.tableFooterView = UIView()
}
override func viewDidAppear(_ animated: Bool) {
super.viewWillAppear(animated)
fetchCoreDataObject()
tableView.reloadData()
}
func fetchCoreDataObject() {
self.fetch { (complete) in
if complete {
if userBudgetCount(0) >= 1 {
userBudgetLabel.text = replaceLabel(number: userMoney[userMoney.count - 1].userMoney)
tableView.isHidden = false
plusButton.isHidden = false
moreBtn.isHidden = false
} else {
tableView.isHidden = true
userBudgetLabel.text = "Bugetul tau"
plusButton.isHidden = true
moreBtn.isHidden = true
}
}
}
}
var fetchedResultsController: NSFetchedResultsController<Budget> {
if _fetchedResultsController != nil {
return _fetchedResultsController!
}
let fetchRequest = NSFetchRequest<Budget>(entityName: "Budget")
// Set the batch size to a suitable number.
fetchRequest.fetchBatchSize = 20
// Edit the sort key as appropriate.
let sortDescriptor = NSSortDescriptor(key: "dateSubmitted" , 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: managedObjectContext!, sectionNameKeyPath: "dateSection", cacheName: nil)
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!
}
var _fetchedResultsController: NSFetchedResultsController<Budget>? = nil
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
tableView.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
return fetchedResultsController.sections!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "expenseCell") as? ExpenseCell else { return UITableViewCell() }
let budget = getUserBudgetAtIndexPath(indexPath: indexPath)
cell.delegate = self
cell.configureCell(budget: budget)
return cell
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.none
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return userBudgetCount(section)
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "Section: \(section)"
}
答案 0 :(得分:0)
func numberOfSections(在tableView:UITableView中) - &gt; Int { guard let count = fetchedResultsController.sections?.count else {return 1} 返回计数 } 尝试安全打开包装:
答案 1 :(得分:0)
当您的视图首次加载表视图时,数据源方法会在结果控制器获取任何数据之前开始调用。因此,无论你在哪里强行解开东西,你都可能会崩溃。
要修复每个地点的这种外观你强行打开(在你使用!
的任何地方)并做更多这样的事情:
func numberOfSections(in tableView: UITableView) -> Int {
return fetchedResultsController.sections?.count ?? 0
}
这将确保某些被返回而不会有崩溃的风险。在某些地方,您可能会遇到更具挑战性的时间来确定默认返回值应该是什么,但它应该是可行的。
??
运算符称为nil-coalescing运算符。语法如下所示:
let foo = someOptionalThing ?? defaultThing
如果someOptionalThing
有值,则会将其分配给foo
,否则defaultThing
会被分配到foo
。
看起来你打电话给return fetchedResultsController.object(at: indexPath) as Budget
结果控制器还没有任何对象,这正是我所期待的。
func getUserBudgetAtIndexPath(indexPath : IndexPath) -> Budget {
// Make sure the section exists
guard fetchedResultsController.sections?.count > indexPath.section else { return Budget() }
// Make sure the section has enough objects
guard fetchedResultsController.sections[indexPath.section].objects?.count > indexPath.row else { return Budget() }
// We made it past both guards, must be safe
return fetchedResultsController.object(at: indexPath) as Budget
}
答案 2 :(得分:0)
对不起。实际上问题出在userBudgetCount
方法中。使用0参数调用此方法
来自fetchCoreDataObject
方法的值因为sections数组最初为空而抛出异常。
使用以下代码行替换uncommentt此函数。请注意,这些代码行尚未编译。
func userBudgetCount(_ section: Int) -> Int{
guard let sections = fetchedResultsController.sections else {
fatalError("No sections in fetchedResultsController")
// comment out the above line of and rerun 0 if don’t want to catch exception
// rerun 0;
}
let sectionInfo = sections[section]
return sectionInfo.numberOfObjects
}
编辑在我编译之后,我在下面添加了更新的代码。请使用它而不是上面。
func userBudgetCount(_ section: Int) -> Int{
guard let sections = fetchedResultsController.sections else {
return 0;
}
if sections.count > section{
let sectionInfo = sections[section]
return sectionInfo.numberOfObjects
}
return 0;
}
答案 3 :(得分:0)
我解决了!
问题不在tableView
填充函数中,但在函数中我尝试检查如果我的实体中有元素,那么我可以使 tableView < / strong>可见
在此代码中
func fetchCoreDataObject() {
self.fetch { (complete) in
if complete {
if userBudgetCount(0) >= 1 {
userBudgetLabel.text = replaceLabel(number: userMoney[userMoney.count - 1].userMoney)
tableView.isHidden = false
plusButton.isHidden = false
moreBtn.isHidden = false
} else {
tableView.isHidden = true
userBudgetLabel.text = "Bugetul tau"
plusButton.isHidden = true
moreBtn.isHidden = true
}
}
}
我尝试检查超出界限的 userBudgetCount(0),因为我尝试检查它是否存在时, NO 部分为0。所以我需要的是检查我的 fetchedResultsController 是否有任何对象,所以我将if userBudgetCount(0) >= 1
替换为if ((fetchedResultsController.fetchedObjects?.count)! > 0)
,现在工作正常。谢谢大家的回答!