从数据库中删除时,RLMException的领域崩溃“对象已被删除或无效”

时间:2020-09-03 12:09:08

标签: ios swift realm

我正在使用Swift在Realm中构建一个项目管理应用程序。

我正在使用DayViewController在TableView中显示项目。为了能够通过滑动操作从数据库(和UI)删除项目,我使用了tableView:commitEditingStyle:forRowAtIndexPath:函数。

但是,每次我尝试从TableView中滑动删除项目时,应用都会崩溃,并出现Realm Exception:

Terminating app due to uncaught exception 'RLMException', reason: 'Object has been deleted or invalidated.'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff23c7127e __exceptionPreprocess + 350
    1   libobjc.A.dylib                     0x00007fff513fbb20 objc_exception_throw + 48
    2   Realm                               0x0000000105e57b44 _ZL17RLMVerifyAttachedP13RLMObjectBase + 84
    3   Realm                               0x0000000105e5d8fc _ZN12_GLOBAL__N_18getBoxedIN5realm10StringDataEEEP11objc_objectP13RLMObjectBasem + 28
    4   Realm                               0x0000000105e5d8d7 ___ZN12_GLOBAL__N_115makeBoxedGetterIN5realm10StringDataEEEP11objc_objectm_block_invoke + 39
    5   Social Media Management App         0x00000001055d9cdd $s27Social_Media_Management_App17DayViewControllerC05tableF0_12cellForRowAtSo07UITableF4CellCSo0mF0C_10Foundation9IndexPathVtF + 973
    6   Social Media Management App         0x00000001055da055 $s27Social_Media_Management_App17DayViewControllerC05tableF0_12cellForRowAtSo07UITableF4CellCSo0mF0C_10Foundation9IndexPathVtFTo + 165
    7   UIKitCore                           0x00007fff48297462 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 781
    8   UIKitCore                           0x00007fff4826043b -[UITableView _updateVisibleCellsNow:] + 3081
    9   UIKitCore                           0x00007fff4828055f -[UITableView layoutSubviews] + 194
    10  UIKitCore                           0x00007fff485784bd -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2478
    11  QuartzCore                          0x00007fff2b131db1 -[CALayer layoutSublayers] + 255
    12  QuartzCore                          0x00007fff2b137fa3 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 517
    13  QuartzCore                          0x00007fff2b1438da _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 80
    14  QuartzCore                          0x00007fff2b08a848 _ZN2CA7Context18commit_transactionEPNS_11TransactionEd + 324
    15  QuartzCore                          0x00007fff2b0bfb51 _ZN2CA11Transaction6commitEv + 643
    16  QuartzCore                          0x00007fff2b0c04ba _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 76
    17  CoreFoundation                      0x00007fff23bd3867 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
    18  CoreFoundation                      0x00007fff23bce2fe __CFRunLoopDoObservers + 430
    19  CoreFoundation                      0x00007fff23bce97a __CFRunLoopRun + 1514
    20  CoreFoundation                      0x00007fff23bce066 CFRunLoopRunSpecific + 438
    21  GraphicsServices                    0x00007fff384c0bb0 GSEventRunModal + 65
    22  UIKitCore                           0x00007fff48092d4d UIApplicationMain + 1621
    23  Social Media Management App         0x00000001055d5feb main + 75
    24  libdyld.dylib                       0x00007fff5227ec25 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

我已经对该主题进行了一些研究,根据我的理解,当代码尝试从数据库中删除对象后 尝试访问对象(或对象的属性)时,会发生此错误或无效。

但是,我不确定我的代码的哪一部分试图访问已删除的对象。

DayViewController.swift:

import UIKit
import RealmSwift

class DayViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    // MARK: Variables

    @IBOutlet weak var dayViewTableView: UITableView!
    
    // Realm initialization
    let realm = try! Realm()
    
    var currentDate: String = ""
    var Projects: [Project] = []
    var projectsToken: NotificationToken?
    
    // MARK: View Lifecycle
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupTableView()
        Projects = getProjectsForDay(day: currentDate)
        
        // Observe Realm database for changes and reload tableview
        projectsToken = realm.observe { (notification, realm) in
            self.dayViewTableView.reloadData()
        }
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        projectsToken?.invalidate()
    }
    
    // MARK: Datasource / Delegate Methods
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return Projects.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let dayViewCell = dayViewTableView.dequeueReusableCell(withIdentifier: DayViewTableViewCell.reuseIdentifier()) as! DayViewTableViewCell
        
        dayViewCell.setupCellLabels(projectName: Projects[indexPath.row].title, notes: Projects[indexPath.row].notes ?? "")
        
        return dayViewCell
    }
    
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == UITableViewCell.EditingStyle.delete {
            let objectToDelete = Projects[indexPath.row]
            do {
                try realm.write {
                    realm.delete(objectToDelete)
                }
            }
            catch {
                print("Error trying to delete object from realm database. \(error)")
            }
        }
    }
    
    // MARK: User defined functions
    
    func getProjectsForDay(day: String) -> [Project] {
        let filteredProjects = realm.objects(Project.self).filter("dueDateString == %@", day)
        return Array(filteredProjects)
    }
    
    func setupTableView() {
        dayViewTableView.register(UINib(nibName: DayViewTableViewCell.nibName(), bundle: nil), forCellReuseIdentifier: DayViewTableViewCell.reuseIdentifier())
        dayViewTableView.delegate = self
        dayViewTableView.dataSource = self
        
        dayViewTableView.rowHeight = UITableView.automaticDimension
        dayViewTableView.estimatedRowHeight = 54.0
    }

}

1 个答案:

答案 0 :(得分:2)

因为删除和项后阵列未更新。 //观察Realm数据库进行更改并重新加载tableview

projectsToken = realm.observe { (notification, realm) in
        projects = getProjectsForDay(day: currentDate)
        self.dayViewTableView.reloadData()
    }

这应该解决它。 您的对象将保留在数组中,因为领域不会从那里删除它,并且当tableView尝试重新加载它的数据时,它将在删除项目的引用处崩溃。您要实现的目标是通过var项目完成的:结果。 而且您在观察整个领域时有些过分的矫情。您可以在特定查询上添加观察者,但是在修改日期时,要获得这种实时数据会更加困难。

请不要使用大写字母命名属性。

相关问题