0

例外是:

-[__NSArrayI removeExactObject:]: 无法识别的选择器发送到实例

我想在 a 中有一个 a 的表示SKSceneNSTreeController因为我正在使用一个对 a及其代理子Proxy级具有强引用的类,该类的每个实例又被用作树控制器中的表示对象.SKNodeProxy

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];
4

1 回答 1

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是一个不可变数组,如果是,我在尝试删除子项之前将其设为可变副本。

于 2015-06-08T21:31:12.560 回答