2

我正在制作一个简单的应用程序,用户可以在其中使用 swift 和 realm 为数据库添加习惯和完成主题

一切正常,除非我编辑状态并删除对象应用程序崩溃并出现 RLMException 原因:“索引 0 超出范围(必须小于 0)”

我注意到只有当项目是 tableView 中唯一的单元格时才会发生这种情况

如果有人能帮我解决这个问题,我将不胜感激,因为我整天都在努力解决这个问题

习惯对象是:

class Habit: Object {

 dynamic var id = 0
 dynamic var name = ""
 dynamic var state = ""

 convenience init(name: String) {
    self.init()
    self.id = self.incrementaID()
    self.name = name
    self.state = "in Progress"
 }

 override class func primaryKey() -> String? {
    return "id"
 }

 private func incrementaID() -> Int {
    let realm = try! Realm()
    let value = realm.objects(Habit).map{$0.id}.maxElement() ?? 0
    return value + 1
 }}

我正在使用RealmSwiftSwiftFetchedResultsController来自动更新 tableView、swift 2 和 Xcode 7

这是MyHabitsViewController中的TableViewController相关代码

    override func viewDidLoad() {
    super.viewDidLoad()

    // Get the default Realm
    realm = try! Realm()

    let predicate = NSPredicate(value: true)
    let fetchRequest = FetchRequest<Habit>(realm: realm, predicate: predicate)
    let sortDescriptor = SortDescriptor(property: "name", ascending: true)
    let sortDescriptorSection = SortDescriptor(property: "state", ascending: false)

    fetchRequest.sortDescriptors = [sortDescriptorSection, sortDescriptor]

    self.fetchedResultsController = FetchedResultsController<Habit>(fetchRequest: fetchRequest, sectionNameKeyPath: "state", cacheName: nil)
    self.fetchedResultsController!.delegate = self
    self.fetchedResultsController!.performFetch()
}

FetchedResultsControllerDelegate 方法:

func controllerWillChangeContent<T : Object>(controller: FetchedResultsController<T>) {
    tableView.beginUpdates()
}

func controllerDidChangeSection<T : Object>(controller: FetchedResultsController<T>, section: FetchResultsSectionInfo<T>, sectionIndex: UInt, changeType: NSFetchedResultsChangeType) {

    let indexSet = NSIndexSet(index: Int(sectionIndex))

    switch changeType {

    case .Insert:
        tableView.insertSections(indexSet, withRowAnimation: .Fade)

    case .Delete:
        tableView.deleteSections(indexSet, withRowAnimation: .Fade)

    case .Update:
        tableView.reloadSections(indexSet, withRowAnimation: .Fade)

    case .Move:
        tableView.deleteSections(indexSet, withRowAnimation: .Fade)
        tableView.insertSections(indexSet, withRowAnimation: .Fade)
    }
}

func controllerDidChangeObject<T : Object>(controller: FetchedResultsController<T>, anObject: SafeObject<T>, indexPath: NSIndexPath?, changeType: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {

    switch changeType {

    case .Insert:
        tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)

    case .Delete:
        tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)

    case .Update:
        tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)

    case .Move:
        tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
        tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
    }
}

func controllerDidChangeContent<T : Object>(controller: FetchedResultsController<T>) {
    tableView.endUpdates()
}

UITableViewDelegate & UITableViewDataSource

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return self.fetchedResultsController!.numberOfSections()
}

func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return fetchedResultsController!.titleForHeaderInSection(section)
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.fetchedResultsController!.numberOfRowsForSectionIndex(section)
}


func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("HabitInfoCell", forIndexPath: indexPath) as! HabitInfoCell

    let habit = self.fetchedResultsController!.objectAtIndexPath(indexPath)!

    cell.configure(habit)

    // add delete button
    let deleteButton = MGSwipeButton() {

        try! self.realm.write {
            self.realm.delete(habit)
        }
    }
    cell.leftButtons = [deleteButton]

    // add complete button
    let completeButton = MGSwipeButton() {

        try! self.realm.write {
            habit.state = "Completed"
        }
    }
    cell.rightButtons = [completeButton]

    return cell
}
4

1 回答 1

1

当您传递的索引大于领域对象中存在的总计数时,会显示此错误。

  1. 检查您的 Realm DB 是否包含您在 Tableview 上显示的条目。
  2. 在 Mac 上下载 Realm Browser:链接

我遇到了同样的问题,我观察到该条目不是对 Realm DB 进行的。

认为 Realm 已经有条目,我试图获取。从而导致

RLMException reason: 'Index 0 is out of bounds (must be less than 0)'

  1. 使用以下代码在控制台上登录主目录以获取 realm.db 文件:

    让 path = NSHomeDirectory().appending("/Documents/") 打印(路径)

于 2017-01-31T05:17:43.420 回答