Objective C - CCCallFuncND正确传递参数

时间:2013-10-07 14:57:47

标签: iphone objective-c cocos2d-iphone

我一直试图调用下面的函数。似乎无论何时在函数 playNote 中我试图访问我作为参数传递的对象(myNum)它总是崩溃。我很新,我可能不明白如何通过CCCallFuncND传递参数。所有评论都表示赞赏。

这是传递参数 myNum

的调用
id action2 = [CCCallFuncND actionWithTarget:self selector:@selector(playNote:data:) data:(NSNumber *)myNum];

这是整个街区:

- (void)muteAndPlayNote:(NSInteger)noteValue :(CCLayer*)currentLayer
{
myNum = [NSNumber numberWithInteger:noteValue];

NSLog(@"Test the number: %d", [myNum integerValue]);

id action1 = [CCCallFunc actionWithTarget:self selector:@selector(muteAudioInput)];

id action2 = [CCCallFuncND actionWithTarget:self selector:@selector(playNote:data:) data:(NSNumber *)myNum];

id action3 = [CCDelayTime actionWithDuration:3];

id action4 = [CCCallFunc actionWithTarget:self selector:@selector(unmuteAudioInput)];

[currentLayer runAction: [CCSequence actions:action1, action2, action3, action4, nil]];

}

NSLog永远不会显示它在此行崩溃的任何内容。

- (void) playNote:(id)sender data:(NSNumber *)MIDInoteValue

{
NSLog(@"Test number 2: %d", [MIDInoteValue integerValue]);
int myInt = [MIDInoteValue floatValue];
[PdBase sendFloat: 55 toReceiver:@"midinote"];
[PdBase sendBangToReceiver:@"trigger"];
}

3 个答案:

答案 0 :(得分:2)

请注意,如果您使用ARC,CCCallFunc *操作本质上是不安全的。

无论如何,使用CCCallBlock *操作(在ARC下可以安全使用)通常会更好,因为那时你甚至不需要传递数据作为参数,你可以使用块内局部范围的变量:

myNum = [NSNumber numberWithInteger:noteValue];
[CCCallBlock actionWithBlock:^{
    NSInteger myInt = [myNum integerValue];
    // do something with myInt, or just use noteValue directly
}];

PS:检查代码的数据类型一致性。您创建NSNumber myNum作为NSInteger值,稍后您可以通过floatValue方法获取该值,隐式将数字转换为float,然后返回int(改为使用integerValue)。您将其分配给int值,该值仅与32位系统上的int相同,在64位系统上如iPhone 5S NSInteger实际上是64位类型(使用NSInteger而不是{{1} })。

如果您在使用完全相同的数据类型时不一致,则可能会出现令人讨厌的价值转换问题(以及构建64位设备时的问题)。此外,您甚至可能已经收到有关此问题的警告 - 请认真对待这些警告。

答案 1 :(得分:1)

您的方法签名是:

-(void)playNote:(id)sender data:(NSNumber*)MIDInoteValue

但它应该是:

-(void)playNote:(id)sender data:(void*)data

这在CCActionInstant.h中定义为:

typedef void (*CC_CALLBACK_ND)(id, SEL, id, void *);

另外我很确定你从崩溃中得到一些信息,比如控制台输出的调用堆栈结束,如果我错了就会把它粘贴到这里;)

答案 2 :(得分:1)

对于遇到此功能问题的人,以下是工作版本:

id action2 = [CCCallFuncND actionWithTarget:self selector:@selector(playNote:data:) data:(void *)noteValue];

然后是定义:

- (void) playNote:(id)sender data:(void *)midiNoteCode

{
int myNum = midiNoteCode; //void * to int conversion may cause problems on 64bit platform, wrap it into NSInteger
[PdBase sendFloat: (float)myNum toReceiver:@"midinote"];
[PdBase sendBangToReceiver:@"trigger"];

}