开发者

NSInvalidArgumentException when I attempt to call an external method from inside another method

I get the console messages:

2011-10-05 17:21:15.112 Fairstead[4986:207] -[CCSprite translate::::]: unrecognized selector sent to instance 0x546fdb0
2011-10-05 17:21:15.116 Fairstead[4986:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CCSprite translate::::]: unrecognized selector sent to instance 0x546fdb0'



   -(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
    {
        CGPoint touchLocation = [touch locationInView: [touch view]];
        touchLocation = [[CCDirector sharedDirector]convertToGL:touchLocation];
        touchLocation = [self convertToNodeSpace:touchLocation];

        [pc translate:300.0 :touchLocation :pc.position :pc]; //crash on this line

    }

here is the translate method:

-(void) translate:(float) objectVelocity: (CGPoint) translateLocation: (CGPoint) objectLocation:(DefaultObject *) sender
{
    CGPoint moveDifference = ccpSub(translateLocation, objectLocation);
    float distanceToMove = ccpLength(moveDifference);
    float moveDuration = distanceToMove / objectVelocity;

    [sender runAction:[CCMoveTo actionWithDuration:moveDuration position:translateLocation]];
}

The touches ended method is in a different class开发者_开发百科 file than translate.

The translate method is in a DefaultObject class file that is a sub-class of CCSprite

pc is synthesized and the @property is nonatomic, retain

What am I missing?


You are missing the argument labels, both in method definition and method call.

First of all, I can see where you are coming from: in most programming languages including but not limited to C, C++, Java etc a method has the form of:

float acceleration(float speed, float angle) { }

Objective-C, however, is different because you also need to label the arguments:

- (float) accelerationFromSpeed:(float)speed andAngle:(float)angle { }

Now, objC beginners might ask why do we need to label the arguments when we already name them? Consider the following C++ call to our first method above:

float result = obj->acceleration(23, 45);

Now let me ask you, what are 23 and 45 referring to? You would have to go back to the method definition to know that, for example, 23 is speed and 45 is angle. Some programmers might even do the following:

float speed = 23;
float angle = 45;
float result = obj->acceleration(speed, angle);

Still, why do we need to declare variables when we can do the following in Objective-C:

float result = [obj accelerationFromSpeed:23 andAngle:45];

You can now easily know what 23 and 45 mean just from the method call itself. No need to refer back or memorize the method definition header or declare variables.

Back to your code, you need to modify your method definition header to something like:

-(void) translate:(CGPoint)translateLocation  
     withVelocity:(float)objectVelocity 
andObjectLocation:(CGPoint)objectLocation 
        andSender:(DefaultObject *)sender
{
    CGPoint moveDifference = ccpSub(translateLocation, objectLocation);
    float distanceToMove = ccpLength(moveDifference);
    float moveDuration = distanceToMove / objectVelocity;

    [sender runAction:[CCMoveTo actionWithDuration:moveDuration position:translateLocation]];
}

And call it using (made multi-lined here for clarity but you can always collapse it into one line if you prefer):

[pc      
         translate:touchLocation 
      withVelocity:300.0 
 andObjectLocation:pc.position 
         andSender:pc];
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜