Ios 无法识别的选择器发送到实例错误?

Ios 无法识别的选择器发送到实例错误?,ios,objective-c,oop,scenekit,Ios,Objective C,Oop,Scenekit,考虑以下代码: SCNNode *someNode = [[SCNNode alloc] init]; Piece *piece = (Piece *)someNode; [piece pick]; 其中,Piece是SCNNode的一个子类,包含一个名为pick的方法。Xcode正在返回此错误: [SCNNode pick]: unrecognized selector sent to instance 有人能说出我的代码有什么问题吗 编辑: 我也试过这个。同样的问题 - (id)init

考虑以下代码:

SCNNode *someNode = [[SCNNode alloc] init];
Piece *piece = (Piece *)someNode;
[piece pick];
其中,Piece是SCNNode的一个子类,包含一个名为pick的方法。Xcode正在返回此错误:

[SCNNode pick]: unrecognized selector sent to instance
有人能说出我的代码有什么问题吗

编辑:

我也试过这个。同样的问题

- (id)initPieceWithNode:(SCNNode *)node {

    if (self = [super init]) {
         self = (Piece *)[node copy];
    }

return self;
}

在这里,您将SCNNode转换为一个片段,而不是创建一个片段对象。如果进行转换,该方法将不会神奇地出现在SCNNode中

你应该这样做:

Piece *piece = [Piece pieceWithNode:someNode];
例如:

+ (Piece *)pieceWithNode:(SCNNode *)aNode {
     Piece *newPiece = [Piece new];

     newPiece.property1 = aNode.propertyX
     newPiece.property2 = aNode.propertyY
     ...

     return newPiece;
}
这是最好的方法

编辑2: 根据评论:


如果
Piece
SCNNode
的一个子类,那么它就是nougth

   Piece *piece = [[Piece alloc] init];
   [piece pick];

如果您正在处理多态类型,那么您应该查询对象的确切类型,并对该对象执行适合该类型的操作

例如,您有:

@interface SCNNode : NSObject
- (void)baseMethod;
@end

@interface Piece : SCNNode
- (void)derivedMethod;
@end
那么处理代码的行为应该如下所示:

- (void)doSomethingWithNode:(SCNNode *)node
{
    [node baseMethod];
    if ([node isKindOfClass:[Piece class]]) {
        [node derivedMethod];
    }
}

处理代码不适合将基类型转换为派生类型,因为我怀疑它是否能够提供对象的附加属性。如果您正在转换,那么其他地方有问题。

someNode
不是
片段
对象,它是
SCNNode
对象。您不能简单地将基类实例强制转换为子类实例并期望它工作。@rmaddy但是它返回的
pick
不是
SCNNode
的方法,而OP在
SCNNode
@burhanuddinsunnelwala不,
pick
Piece
的方法,而不是
SCNNode
。谢谢@rmaddy。是的,挑选是一种拼凑的方法。抱歉搞混了。哦,那你是对的!谢谢你的回答。你能告诉我pieceWithNode方法是什么样的吗?我是Objective-C的绝对初学者:)哦,我不知道,我给你的是你应该这样做的方式。我不知道SCNNode和Piece类,所以我无法告诉您方法名称是否正确。我自己编写了Piece类,而SCNNode是Apple的场景工具包节点类。Piece是SCNNode的一个子类。无论如何,谢谢你的回答。我正在尝试让它工作,如果它工作,我将标记您的答案正确。因此,在您的Piece类中,创建一个+方法名为pieceWithNode:(SCNNode*)然后在其中,读取节点中需要的属性,并将它们复制到全新创建的工件对象中,然后返回工件对象。希望它能为您提供正确的指导。在最初的问题中,用户是自己创建节点的。因此,不需要分配一个
SCNNode
,然后分配一个
片段来复制刚刚创建的节点。只需使用
Piece*Piece=[[Piece alloc]init]分配一个
Piece
;[单件挑选]
- (void)doSomethingWithNode:(SCNNode *)node
{
    [node baseMethod];
    if ([node isKindOfClass:[Piece class]]) {
        [node derivedMethod];
    }
}