Swift 4,Realm 3.5
我在NSOutlineView
上设置了一个适用于插入和修改的领域通知,但删除始终会导致此异常:
2018-05-23 11:57:09.890455-0700 MyApp[57060:9443837] [General] Object has been deleted or invalidated.
2018-05-23 11:57:09.893594-0700 MyApp[57060:9443837] [General] (
0 CoreFoundation 0x00007fff27eeb32b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x00007fff4f565c76 objc_exception_throw + 48
2 Realm 0x000000010074696f ___ZN12_GLOBAL__N_115makeBoxedGetterIN5realm10StringDataEEEP11objc_objectm_block_invoke + 289
3 Foundation 0x00007fff29f7404c -[NSObject(NSKeyValueCoding) valueForKey:] + 284
4 Realm 0x00000001007618b1 -[RLMObjectBase valueForKey:] + 85
5 Realm 0x0000000100762b77 -[RLMObjectBase hash] + 145
6 Foundation 0x00007fff29f4a3eb probeGC + 80
7 Foundation 0x00007fff29f4d994 -[NSConcreteMapTable removeObjectForKey:] + 56
8 AppKit 0x00007fff255d262f _NSOVFreeRowEntry + 59
9 AppKit 0x00007fff25abc83a __70-[NSOutlineView _removeItemsAtIndexes:inParentRowEntry:withAnimation:]_block_invoke + 253
...
以下是我的通知观察者的样子:
let realm = try! Realm()
let results = realm.objects(Workspace.self).sorted(byKeyPath: "order", ascending: true)
tokenWorkspace?.invalidate()
tokenWorkspace = results.observe { [weak self] (changes: RealmCollectionChange) in
switch changes {
case .initial:
//The listener is ready
self?.refreshData(reload: true)
case .update(_, let deletions, let insertions, let modifications):
self?.refreshData(reload: false)
self?.workspaceOutlineView.beginUpdates()
self?.workspaceOutlineView.insertItems(at: IndexSet(insertions), inParent: nil, withAnimation: .slideDown)
//--- (!) The crash seems to be on the next line...
self?.workspaceOutlineView.removeItems(at: IndexSet(deletions), inParent: nil, withAnimation: .slideUp)
self?.workspaceOutlineView.reloadData(forRowIndexes: IndexSet(modifications), columnIndexes: IndexSet([0]))
self?.workspaceOutlineView.endUpdates()
case .error(let error): print("\(error)")
}
}
在尝试removeItems
调用之前,我正在workspaces
中刷新我的数据源数组refreshData()
,如下所示:
func refreshData(reload: Bool){
let realm = try! Realm()
let workspaceObjects = realm.objects(Workspace.self).sorted(byKeyPath: "order", ascending: true)
workspaces.removeAll()
workspaces.append(contentsOf: workspaceObjects)
if reload{
workspaceOutlineView.reloadData()
}
}
我无法弄清楚删除对象的访问位置并导致异常。 NSOutlineView
似乎仍然在某个地方引用它。
有什么想法吗?
答案 0 :(得分:0)
两件事:
您在观察闭合中的removeItems(...)
调用为时已晚。该对象已经失效,但是您通过removeItems(...)
调用击中了大纲视图,其中节点仍然引用了失效的对象。
我建议从封闭外部的大纲视图中删除该项目,也许是在处理用户删除请求的action方法中。
第二,您应该查看为removeItems(...)
赋予的索引:
.update枚举中从领域中获得的是相对于领域对象的索引。但是,大纲视图方法期望相对于其父级的索引。因此,“平坦”领域结果中的第十个项目可能是相对于其大纲视图中其父节点的第二个项目。
检查outlineView.childIndex(forItem: ...)
以获得相对子索引。