Reputation:
I followed tutorial from cocos2d official site . I try to create some items for a menu when creating them i pass a selector with one parameter. For each item i pass different selector . I think here is the problem , but i dont see realy why here is the problem. My header file looks :
// When you import this file, you import all the cocos2d classes
#import "cocos2d.h"
#import "CCTouchDispatcher.h"
// HelloWorldLayer
@interface HelloWorldLayer : CCLayer {
CCSprite *first;
CCSprite *second;
}
// returns a CCScene that contains the HelloWorldLayer as the only child
+(CCScene *) scene;
- (void) setUpMenus;
- (void) doSomethingOne: (CCMenuItem *) menuItem;
- (void) doSomethingTwo: (CCMenuItem *) menuItem;
- (void) doSomethingThree: (CCMenuItem *) menuItem;
@end
Implementation file :
// Import the interfaces
#import "HelloWorldLayer.h"
// HelloWorldLayer implementation
@implementation HelloWorldLayer
+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
HelloWorldLayer *layer = [HelloWorldLayer node];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
- (void) doSomethingOne: (CCMenuItem *) menuItem
{
NSLog(@"The first menu was called");
}
- (void) doSomethingTwo: (CCMenuItem *) menuItem
{
NSLog(@"The second menu was called");
}
- (void) doSomethingThree: (CCMenuItem *) menuItem
{
NSLog(@"The third menu was called");
}
// on "init" you need to initialize your instance
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init])) {
first = [CCSprite spriteWithFile:@"seeker.png"];
first.position = ccp(100, 100);
[self addChild:first];
second = [CCSprite spriteWithFile:@"Icon.png"];
second.position = ccp(50, 50);
[self addChild:second];
[self schedule:@selector(nextFrame:)];
[self setUpMenus];
self.isTouchEnabled = YES;
}
return self;
}
- (void) registerWithTouchDispatcher {
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
- (BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
return YES;
}
- (void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
CGPoint location = [self convertTouchToNodeSpace: touch];
[second stopAllActions];
[second runAction: [CCMoveTo actionWithDuration:1 position:location]];
}
- (void) nextFrame:(ccTime)dt {
first.position = ccp( first.position.x + 100*dt, first.position.y );
if (first.position.x > 480+32) {
first.position = ccp( -32, first.position.y );
}
}
- (void) setUpMenus {
CCMenuItemImage *menuItem1 = [CCMenuItemImage itemFromNormalImage:@"myfirstbutton.png"
selectedImage:@"myfirstbutton_selected.png"
target:self
selector:@selector(doSomenthingOne:)];
CCMenuItemImage *menuItem2 = [CCMenuItemImage itemFromNormalImage:@"mysecondbutton.png"
selectedImage:@"mysecondbutton_selected.png"
target:self
selector:@selector(doSomenthingTwo:)];
CCMenuItemImage *menuItem3 = [CCMenuItemImage itemFromNormalImage:@"mythirdbutton.png"
selectedImage:@"mythirdbutton_selected.png"
target:self selector:@selector(doSomenthingThree:)];
CCMenu *myMenu = [CCMenu menuWithItems:menuItem1,menuItem2,menuItem3, nil];
[myMenu alignItemsVertically];
[self addChild:myMenu];
}
// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
// in case you have something to dealloc, do it in this method
// in this particular example nothing needs to be released.
// cocos2d will automatically release all the children (Label)
// don't forget to call "super dealloc"
[super dealloc];
}
@end
Upvotes: 2
Views: 2861
Reputation: 64002
You've got the same typo in all three menu item creation calls. You're telling the menu items that the selector they should use is called doSomenthing...
(note the spurious n in the middle):
CCMenuItemImage *menuItem1 = [... selector:@selector(doSomenthingOne:)];
CCMenuItemImage *menuItem2 = [... selector:@selector(doSomenthingTwo:)];
CCMenuItemImage *menuItem3 = [... selector:@selector(doSomenthingThree:)];
but the actual names of your methods are doSomethingOne:
, doSomethingTwo:
, and doSomethingThree:
.
The exact cause of the error message is that later, when the menu item needs to perform that selector, it will ask your class to tell it the method signature for the selector you gave it. Since you gave the item an incorrect selector, your class doesn't know the signature, and it returns nil
. The menu item tries to construct an NSInvocation
object anyways to perform its action, which fails because the invocation can't be created with a nil
signature.
Fix the typos and everything should work fine.
Upvotes: 1