例外是:
- [__ NSArrayI removeExactObject:]:无法识别的选择器发送到实例
我希望在SKScene
中代表NSTreeController
,因为我使用的是Proxy
类,其中包含对SKNode
的强引用到它的代理子节点,Proxy
类的每个实例又被用作树控制器中的表示对象。
NSTreeController
|-Proxy -> SKScene
|-Proxy -> |-SKSpriteNode
|-Proxy -> |-SKNode
|-Proxy -> |-SKSpriteNode
|-Proxy -> |-SKShapeNode
通过Proxy类
中的这些方法将所有节点添加或移除到场景中@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
这是我如何使用场景填充树控制器
[_treeController setContent:[Proxy proxyWithNode:scene]];
问题在于,当树控制器尝试从其父节点中删除代理节点时,SKNode
会抛出上面的异常
这就是我删除代理节点的方式
[_treeController removeObjectAtArrangedObjectIndexPath:indexPath];
答案 0 :(得分:0)
这是我想出的快速而肮脏的修复:
- (void)setChildren:(NSMutableArray *)children {
id privateChildren = [_node valueForKey:@"_children"];
if (![privateChildren isKindOfClass:[NSMutableArray class]]) {
[_node setValue:[privateChildren mutableCopy] forKey:@"_children"];
}
[_node removeAllChildren];
//[self cleanUpChildren:_node];
//...
}
我检查私有ivar _children
是否是一个不可改变的数组,如果是这样的话,我会在尝试删除子代之前将其作为一个可变副本。