You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
dynamic var subnodes = [Node]()
...
func mapping(map: Map) {
// other properties....
subnodes <- map["subnodes"]
}
When I get this json string like this: let json = goalDocument?.toJSONString(prettyPrint: true)
Object mapper reassigns the array to the object at the subnodes <- map["subnodes"] line, triggering KVO which causes a lot of work to be done elsewhere (NSTreeController / NSOutlineView).
Is there a way to avoid this assignment happening? It doesn't seem to be necessary?
Here's the stack trace through the KVO notification from the JSONString query.
#0 0x0000000100087693 in NodeDataSource.outlineViewItemDidExpand(Notification) -> () at /Users/mtozer/code/mycode/Apps/Sword/Sword/NodeDataSource.swift:113
#1 0x0000000100087c17 in @objc NodeDataSource.outlineViewItemDidExpand(Notification) -> () ()
#2 0x00007fff772b7a6c in __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ ()
#3 0x00007fff772b796b in _CFXRegistrationPost ()
#4 0x00007fff772b76d2 in ___CFXNotificationPost_block_invoke ()
#5 0x00007fff77274d63 in -[_CFXNotificationRegistrar find:object:observer:enumerator:] ()
#6 0x00007fff77273d9c in _CFXNotificationPost ()
#7 0x00007fff78c9aa37 in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#8 0x00007fff74fb5666 in -[NSOutlineView _postItemDidExpandNotification:] ()
#9 0x00007fff74edcff7 in -[NSOutlineView _expandItemEntry:expandChildren:startLevel:] ()
#10 0x00007fff7510a813 in -[NSOutlineView reloadItem:reloadChildren:] ()
#11 0x00007fff7548f51b in -[NSOutlineViewBinder _childrenChangedForNode:] ()
#12 0x00007fff750bc82b in -[NSOutlineViewBinder observeValueForKeyPath:ofObject:change:context:] ()
#13 0x00007fff78cd771d in NSKeyValueNotifyObserver ()
#14 0x00007fff78cd6fb4 in NSKeyValueDidChange ()
#15 0x00007fff78ca5e96 in -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] ()
#16 0x00007fff750ba4a9 in -[NSTreeControllerTreeNode updateChildNodesForKeyPath:affectedIndexPaths:] ()
#17 0x00007fff757152eb in -[NSTreeControllerTreeNode observeValueForKeyPath:ofObject:change:context:] ()
#18 0x00007fff78cd771d in NSKeyValueNotifyObserver ()
#19 0x00007fff78cd6fb4 in NSKeyValueDidChange ()
#20 0x00007fff78e15c37 in -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:usingBlock:] ()
#21 0x00007fff78c9ad1d in -[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:] ()
#22 0x00007fff78d0359b in _NSSetObjectValueAndNotify ()
#23 0x0000000100031b84 in Node.mapping(map : Map) -> () at /Users/mtozer/code/mycode/Apps/Sword/Sword/Goals.swift:325
#24 0x00000001000324f4 in protocol witness for BaseMappable.mapping(map : Map) -> () in conformance Node ()
#25 0x0000000100687848 in Mapper.toJSON(A) -> [String : Any] at /Users/mtozer/code/mycode/Apps/Sword/Pods/ObjectMapper/Sources/Mapper.swift:278
#26 0x0000000100687a94 in Mapper.(toJSONArray([A]) -> [[String : Any]]).(closure #1) at /Users/mtozer/code/mycode/Apps/Sword/Pods/ObjectMapper/Sources/Mapper.swift:286
#27 0x0000000100687b12 in thunk ()
#28 0x0000000100687c2c in partial apply for thunk ()
#29 0x00000001007d7ad6 in Collection.map<A> ((A.Iterator.Element) throws -> A1) throws -> [A1] ()
#30 0x00000001006879fb in Mapper.toJSONArray([A]) -> [[String : Any]] at /Users/mtozer/code/mycode/Apps/Sword/Pods/ObjectMapper/Sources/Mapper.swift:287
#31 0x0000000100692bf4 in static ToJSON.objectArray<A where ...> ([A], map : Map) -> () at /Users/mtozer/code/mycode/Apps/Sword/Pods/ObjectMapper/Sources/ToJSON.swift:118
#32 0x000000010068e98a in >>> infix<A where ...> ([A], Map) -> () at /Users/mtozer/code/mycode/Apps/Sword/Pods/ObjectMapper/Sources/Operators.swift:248
#33 0x000000010068e8f1 in <- infix<A where ...> (inout [A], Map) -> () at /Users/mtozer/code/mycode/Apps/Sword/Pods/ObjectMapper/Sources/Operators.swift:241
#34 0x0000000100031b44 in Node.mapping(map : Map) -> () at /Users/mtozer/code/mycode/Apps/Sword/Sword/Goals.swift:325
#35 0x00000001000324f4 in protocol witness for BaseMappable.mapping(map : Map) -> () in conformance Node ()
#36 0x0000000100687848 in Mapper.toJSON(A) -> [String : Any] at /Users/mtozer/code/mycode/Apps/Sword/Pods/ObjectMapper/Sources/Mapper.swift:278
#37 0x00000001006926af in static ToJSON.object<A where ...> (A, map : Map) -> () at /Users/mtozer/code/mycode/Apps/Sword/Pods/ObjectMapper/Sources/ToJSON.swift:106
#38 0x0000000100692a29 in static ToJSON.optionalObject<A where ...> (A?, map : Map) -> () at /Users/mtozer/code/mycode/Apps/Sword/Pods/ObjectMapper/Sources/ToJSON.swift:113
#39 0x000000010068db2d in >>> infix<A where ...> (A?, Map) -> () at /Users/mtozer/code/mycode/Apps/Sword/Pods/ObjectMapper/Sources/Operators.swift:122
#40 0x000000010068d990 in <- infix<A where ...> (inout A?, Map) -> () at /Users/mtozer/code/mycode/Apps/Sword/Pods/ObjectMapper/Sources/Operators.swift:115
#41 0x0000000100029f55 in GoalDocument.mapping(map : Map) -> () at /Users/mtozer/code/mycode/Apps/Sword/Sword/Goals.swift:81
#42 0x000000010002a934 in protocol witness for BaseMappable.mapping(map : Map) -> () in conformance GoalDocument ()
#43 0x0000000100687848 in Mapper.toJSON(A) -> [String : Any] at /Users/mtozer/code/mycode/Apps/Sword/Pods/ObjectMapper/Sources/Mapper.swift:278
#44 0x0000000100689c25 in Mapper.toJSONString(A, prettyPrint : Bool) -> String? at /Users/mtozer/code/mycode/Apps/Sword/Pods/ObjectMapper/Sources/Mapper.swift:308
#45 0x000000010067fd05 in BaseMappable.toJSONString(prettyPrint : Bool) -> String? at /Users/mtozer/code/mycode/Apps/Sword/Pods/ObjectMapper/Sources/Mappable.swift:76
#46 0x0000000100014ef1 in Document.data(ofType : String) throws -> Data at /Users/mtozer/code/mycode/Apps/Sword/Sword/Document.swift:119
#47 0x00000001000152cb in @objc Document.data(ofType : String) throws -> Data ()
#48 0x00007fff75181950 in -[NSDocument writeToURL:ofType:error:] ()
The text was updated successfully, but these errors were encountered:
subnodes is not reassigned in the toJSON process. I believe, the issue that you are experiencing arises because the <- operator uses the inout flag for the left hand parameter. This is necessary when mapping from JSON to model.
So when toJSONString is called, KVO assumes that subnodes is modified due to the inout flag.
One solution which is not that elegant that should solve your issue is the following:
if map.mappingType == .toJSON {
subnodes >>> map["subnodes"]
} else if map.mappingType == .fromJSON {
subnodes <- map["subnodes"]
}
The >>> is used only for generating JSON and does not use the inout flag.
I have a model which represents a tree of nodes
The mapping function looks like this
When I get this json string like this:
let json = goalDocument?.toJSONString(prettyPrint: true)
Object mapper reassigns the array to the object at the
subnodes <- map["subnodes"]
line, triggering KVO which causes a lot of work to be done elsewhere (NSTreeController / NSOutlineView).Is there a way to avoid this assignment happening? It doesn't seem to be necessary?
Here's the stack trace through the KVO notification from the JSONString query.
The text was updated successfully, but these errors were encountered: