我正在使用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
}
}
答案 0 :(得分:2)
因为删除和项后阵列未更新。 //观察Realm数据库进行更改并重新加载tableview
projectsToken = realm.observe { (notification, realm) in
projects = getProjectsForDay(day: currentDate)
self.dayViewTableView.reloadData()
}
这应该解决它。 您的对象将保留在数组中,因为领域不会从那里删除它,并且当tableView尝试重新加载它的数据时,它将在删除项目的引用处崩溃。您要实现的目标是通过var项目完成的:结果。 而且您在观察整个领域时有些过分的矫情。您可以在特定查询上添加观察者,但是在修改日期时,要获得这种实时数据会更加困难。
请不要使用大写字母命名属性。