2011-06-18 67 views
2

所以我這樣做是爲了初始化我的選擇:選擇器在cocos2d調度方法

//In .h 

SEL selectors[3]; 

//In .m 

selectors[0] = @selector(rotate); 
selectors[1] = @selector(discharge); 

而現在的問題是:

當我在cocos2d稱這在我的init()方法是這樣的:

[self performSelector:selectors[0]]; 

它工作正常,但是當我把這行代碼中,通過調度([self schedule:@selector(moveThings:)])在我的init方法的在cocos2d結束時被調用的方法稱爲moveThings它給EXC_BAD_ACCESS。調度東西有什麼問題?

UPDATE:

我已發現存在與旋轉功能的問題(該函數被存儲在選擇器[0])。這裏是:

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

如果我評論方法的內容,它通過moveThings和init調用時工作正常。

如果我改變方法內容有:

((CCSprite *)[creature objectAtIndex:0]).rotation++; 

它失敗......但同樣,我想指出,所有這些事情,如果我把它在我的init方法做工作,甚至如果我通過moveThings:方法通過調度方法調用失敗,它將無法工作(除了當我取出rotate方法的內容時)。

進一步更新:

如果我稱:

((CCSprite *)[creature objectAtIndex:0]).rotation++; 

在moveThings(其是,正如我以前說過的,由schedule:(SEL)方法調用的)它將失敗。只要它不是通過時間表調用的方法調用的,它就可以工作。

+0

崩潰日誌實際上說了什麼? –

+0

@Deepak:對不起,我一直在編輯它錯誤...我沒有粘貼它,應該有...選擇器適用於moveThings只是不選擇[0] ... – Dair

+0

@Deepak:崩潰日誌說'程序收到EXC_BAD_ACCESS' – Dair

回答

6

的問題是,當你調用performSelector只有兩種選擇:

  1. 有你的選擇沒有參數,並留下了「:」關@selector(富)的定義。
  2. 有你的選擇需要一個或兩個參數這都應該是一個NSObject或子類

它是搞亂你在這裏我懷疑後者。

這裏有三種形式的performSelector

- (id)performSelector:(SEL)aSelector; 
- (id)performSelector:(SEL)aSelector withObject:(id)object; 
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2; 

你會注意到,withObject參數都id類型,是一個目標C的對象。

你想使用選擇需要ccTime這是一個float,因爲它是PARAM一個Objective C的對象,這就是爲什麼事情正在崩潰:

-(void)rotate:(ccTime)delta; 

一種選擇是使採用一個包裹ccTime和解開它並調用rotate:(ccTime)方法的包裝方法,包括:

- (void) wrappedRotate: (NSNumber*) inDelta 
{ 
    [self rotate: [inDelta floatValue]]; 
} 

然後使用

selectors[0] = @selector(wrappedRotate:); 

,然後調用通過:

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

... 

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

一個你感到困惑的原因是因爲cocos2d的是稍微更復雜的方式使用@selector(見CCScheduler.m在CCTimer :: initWithTarget:選擇:interval:和CCTimer :: update:特別是方法)。

免責聲明:代碼輸入到SO中,因此不用編譯器進行檢查,但是您需要的內容應該在這裏。

+0

+1。系統想要保留傳遞的對象,並且在普通的float上這樣做會崩潰。 – Eiko

+0

謝謝,這是一個問題,我也忘了說'self.creature' ...因爲我只想要一個例子...... – Dair

0

可以肯定的一個問題是,您正在使用在.h中聲明的變量,同時在相對的.m中初始化它。根據鏈接我不確定只有一個變量selectors將存在(以便包含.h的不同文件將具有不同的版本)。所有的

首先,我建議你嘗試添加關鍵字extern

extern SEL selectors[3]; 

要告訴你的連接器,它是相對.m內初始化,並只使用一個。

+0

使用extern給出錯誤...'expected specifier-qualifier-list before 「extern''。 – Dair

+0

它不應該,我只是在XCode嘗試,應該有不同的東西。也許你在課堂上宣佈SEL?但它是一個實例變量還是隻是一個變量?你的問題並不清楚。 – Jack

+0

是的,我在一個類中聲明瞭選擇器。我相信這是一個伊娃。 – Dair

0

我覺得從它- (void)rotate;而不是- (void)rotate:(ccTime)dt;

,你應該也調整你的選擇你的方法定義你的問題造成的。

+0

這不是它不會調用它,它只是當我通過調用方法調用它時:'[self schedule:(SEL)]'它不會工作。如果我只是調用moveThings方法,而不使用它的調度方法,它將起作用,如果我連續兩次執行選擇器,它也可以工作... – Dair

+0

遇到問題。檢查編輯的答案。 –

+0

哎呀,其實,我有它定義你的建議,我也改變了它,寫錯了問題... – Dair

0

如果你的方法沒有任何參數,那麼不要在你的選擇器調用中使用冒號。

// Requires @selector(foo:) 
- (void) foo:(id)sender; 
// Requires @selector(foo) 
- (void) foo; 
相關問題