The exception is:
-[__NSArrayI removeExactObject:]: unrecognized selector sent to instance
I want to have a representation of a SKScene
in a NSTreeController
, for that I’m using a Proxy
class that holds a strong reference to a SKNode
and to its proxy children, with each instance of the Proxy
class in turn being used as the represented object in the tree controller.
NSTreeController
|-Proxy -> SKScene
|-Proxy -> |-SKSpriteNode
|-Proxy -> |-SKNode
|-Proxy -> |-SKSpriteNode
|-Proxy -> |-SKShapeNode
All nodes are added or removed to the scene via these methods in the Proxy class
@interface Proxy : NSObject
+ (instancetype)proxyWithNode:(id)node;
@end
@implementation Proxy {
SKNode *_node;
NSMutableArray *_proxyChildren;
}
+ (instancetype)proxyWithNode:(id)node {
if (node) {
Proxy *proxy = [[Proxy alloc] init];
proxy.node = node;
return proxy;
}
return nil;
}
- (void)setNode:(id)node {
_proxyChildren = [NSMutableArray array];
for (id child in [node children]) {
Proxy *childProxy = [Proxy proxyWithNode:child];
[_proxyChildren addObject:childProxy];
}
_node = node;
}
- (id)node {
return _node;
}
- (void)setChildren:(NSMutableArray *)children {
//[_node removeAllChildren];
[self cleanUpChildren:_node];
for (Proxy *child in children) {
[_node addChild:child.node];
}
_proxyChildren = children;
}
- (NSMutableArray *)children {
return _proxyChildren;
}
- (void)cleanUpChildren:(SKNode *)node {
for (SKNode *child in node.children) {
[self cleanUpChildren:child];
//assert(child.parent == node);
@try {
//NSLog(@"\n%p %p\n%@\n%@\n\n", node, child, node, child);
[child removeFromParent];
}
@catch (NSException *exception) {
NSLog(@"WTF!");
}
}
}
@end
This is how to I populate the tree controller with the scene
[_treeController setContent:[Proxy proxyWithNode:scene]];
The problem is that at some point when the tree controller tries to remove a proxy node from its parent the SKNode
throws the exception above
This is how I'm removing a proxy node
[_treeController removeObjectAtArrangedObjectIndexPath:indexPath];
This is the quick and dirty fix I came up with:
I check whether the private ivar
_children
is an inmutable array, if so I make it a mutable copy before trying to remove the children.