Почему -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
является неизменным массивом, если это так, я делаю его изменяемой копией, прежде чем пытаться удалить потомков.