选择器采用Cocos2d调度方法

Dai*_*air 2 objective-c selector cocos2d-iphone

所以我这样做是为了初始化我的选择器:

//In .h

SEL selectors[3];

//In .m

selectors[0] = @selector(rotate);
selectors[1] = @selector(discharge);
Run Code Online (Sandbox Code Playgroud)

这是问题所在:

当我在Cocos2d中的init方法中调用它时,如下所示:

[self performSelector:selectors[0]];
Run Code Online (Sandbox Code Playgroud)

它工作正常,但是当我在一个名为moveThings的方法中调用这行代码时,它通过[self schedule:@selector(moveThings:)]在Cocos2d的init方法结束时的schedule()调用它给出EXC_BAD_ACCESS.安排事情有什么问题?

更新:

我发现旋转功能有问题(该功能存储在选择器[0]中).这里是:

-(void)rotate:(ccTime)delta {
    if (((CCSprite *)[creature objectAtIndex:0]).rotation < 360) {
        ((CCSprite *)[creature objectAtIndex:0]).rotation++;
    }
    else {
        ((CCSprite *)[creature objectAtIndex:0]).rotation++;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我评论方法的内容,它通过moveThings和init调用时工作正常.

如果我用以下方法更改方法内容:

((CCSprite *)[creature objectAtIndex:0]).rotation++;
Run Code Online (Sandbox Code Playgroud)

它失败了...但是,我想再说一遍,如果我在我的init方法中调用它,所有这些东西都能正常工作,甚至连续两次调用它,但它不起作用(除非我取出它旋转方法的内容)如果我通过moveThings:方法调用它,通过调度方法调用它失败.

进一步更新:

如果我打电话:

((CCSprite *)[creature objectAtIndex:0]).rotation++;
Run Code Online (Sandbox Code Playgroud)

在moveThings(正如我之前所说的那样,由schedule:(SEL)方法调用)它失败了.只要不通过调度方法调用它就可以调用它.

Dad*_*Dad 6

问题是当你调用performSelector时,只有两个选项:

  1. 让你的选择器不带参数,并在@selector(foo)定义中保留":".
  2. 让你的选择器采用一个或两个参数,它们都必须是NSObject或子类

我怀疑是后者让你搞砸了.

以下是三种形式performSelector:

- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
Run Code Online (Sandbox Code Playgroud)

您会注意到withObject参数都是idObjective C对象的类型.

您尝试使用的选择器采用的ccTime是一个float不是 Objective C对象,因为它是param,这就是事情崩溃的原因:

-(void)rotate:(ccTime)delta;
Run Code Online (Sandbox Code Playgroud)

一种选择是创建一个包装器方法,它将包装ccTime并解包并调用rotate:(ccTime)方法:

- (void) wrappedRotate: (NSNumber*) inDelta
{
    [self rotate: [inDelta floatValue]];
}
Run Code Online (Sandbox Code Playgroud)

然后用

selectors[0] = @selector(wrappedRotate:);
Run Code Online (Sandbox Code Playgroud)

然后致电:

[self schedule: @selector(moveThings:)]);  // cocos2d schedule

... 

- (void) moveThings: (ccTime) dt
{
   [self performSelector: selectors[0] withObject: [NSNumber numberWithFloat: dt]];
  ...
}
Run Code Online (Sandbox Code Playgroud)

您感到困惑的一个原因是因为Cocos2d以更复杂的方式使用@selector(请参阅CCTimer :: initWithTarget中的CCScheduler.m:selector:interval:和CCTimer :: update:方法).

免责声明:代码输入SO所以不用编译器检查,但你需要的本质应该在这里.