2011-02-13 32 views
0

我需要將touchesBegan的觸摸和事件傳遞給由performSelector調用的我自己的方法。我正在使用NSInvocation來打包參數,但是我遇到了目標問題。如何讓performSelector使用NSInvocation?

我這樣做的原因是我可以處理其他滾動事件。

這裏是我的代碼:

- (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event 
{   
    UITouch *theTouch = [touches anyObject]; 

    switch ([theTouch tapCount]) 
    { 
     case 1: 
      NSInvocation *inv = [NSInvocation invocationWithMethodSignature: [self methodSignatureForSelector:@selector(handleTap: withEvent:)]]; 
      [inv setArgument:&touches atIndex:2]; 
      [inv setArgument:&event atIndex:3]; 
      [inv performSelector:@selector(invokeWithTarget:) withObject:[self target] afterDelay:.5]; 
      break; 
    } 
} 

凡handleTap被定義爲:

-(IBAction)handleTap:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [super touchesBegan:touches withEvent:event]; 
} 

我的問題是,當我編譯它,我得到一個警告:

'CategoryButton' 很多不響應'目標'

當我運行它時,它崩潰了:

- [CategoryButton目標]:無法識別的選擇發送到實例0x5b39280

我必須承認,我真的不明白什麼目標試圖在這裏做,它是如何設置的。

感謝您的幫助。

回答

2

我認爲您需要花一些時間仔細閱讀您的代碼,逐行。

[inv performSelector:@selector(invokeWithTarget:) withObject:[self target] afterDelay:.5]; 

這不是在做你認爲的事情。一秒的一半執行此方法後,會出現這種情況:

[inv invokeWithTarget:[self target]]; 

首先,你的CategoryButton類沒有一個方法叫做target。其次,爲什麼延遲?如果您正在使用這些觸摸進行滾動,則延遲0.5秒對用戶來說將會非常痛苦。

你爲什麼要使用NSInvocation類?如果你真的需要的延遲,你可以簡單地使用performSelector:方法對你CategoryButton實例:

NSArray *params = [NSArray arrayWithObjects:touches, event, nil]; 
[self performSelector:@selector(handleTap:) withObject:params afterDelay:0.5]; 

通知的performSelector:方法只支持一個論點,所以你要包起來一個NSArray。 (或者,您可以使用NSDictionary。)

您將不得不更新您的handleTap:方法來接受NSArray/NSDictionary並根據需要攔截參數。

但同樣,如果你不需要延時,爲什麼不直接調用該方法自己:

- (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event 
{   
    UITouch *theTouch = [touches anyObject]; 

    switch ([theTouch tapCount]) 
    { 
     case 1: 
      [super touchesBegan:touches withEvent:event]; 
     break; 
    } 
} 

也許我誤解你的意圖,但似乎你正在做這樣更復雜比它需要。

+0

感謝您通過NSArray傳遞參數的幫助,這是難題。延遲是爲了管理點擊。如果在此時間內有滾動,則點擊被取消。這種方法似乎工作得很好。 – iphaaw 2011-02-13 23:24:02

0

我必須承認我並不真正瞭解目標在這裏做什麼以及它是如何設置的。

目標是您希望執行調用的對象。您遇到崩潰是因爲您選擇的對象 - [self] - 不會響應target消息。我想你可能對你需要通過的內容有點困惑。

用你現在的代碼,你要求你的調用在selftarget屬性上執行。你可能不想這樣做 - 我會假設你想讓你的調用簡單地在self上執行。在這種情況下,使用這個:

[inv performSelector:@selector(invokeWithTarget:) withObject:self afterDelay:.5]; 
+0

我實際上使用了上述方法,這意味着我可以完全擺脫NSInvocation。我認爲你是對的,自己會很好。 – iphaaw 2011-02-13 23:28:38