Почему -removeFromParent в SKNode вызывает это исключение?

Исключение составляет:

- [__ 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];

1 ответ

Это быстрое и грязное исправление, которое я придумал:

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

    //...
}

Я проверяю, является ли частный ивар _children является неизменным массивом, если это так, я делаю его изменяемой копией, прежде чем пытаться удалить потомков.

Другие вопросы по тегам