2014-02-24 68 views
1

我正在爲iOS 7做一個程序,但是因爲我在幾個視圖中使用了幾乎相同的方法,所以我想創建一個覆蓋大部分方法的通用類,對於每個視圖都使用一種回調方法進行最終觸摸。我在視圖以下代碼:作爲另一個類的參數的Objective-C回調方法

// On top of the view .m 
#import "Common.h" 

// Method which will be called. 
-(void)doSomething 
{ 
    NSLog(@"doSomething..."); 

    [Common target:self method:@selector(callbackMethod)]; 
} 

// Method I want to be called. 
+(void)callbackMethod 
{ 
    NSLog(@"Should come here..."); 
} 

的COMMON.H是如下:

#import <Foundation/Foundation.h> 

@interface Common : NSObject 

+(void)target:(Class)object method:(SEL)selector; 

@end 

的Common.m被如下:

+(void)target:(Class)object method:(SEL)selector 
{ 
    NSLog(@"target..."); 
    if ([object respondsToSelector:@selector(selector)]) 
    { 
     [object performSelector:@selector(selector)]; 
    } else { 
     NSLog(@"%@", object); 
    } 
} 

在運行時,它只有輸出: doSomething ..., target ..., < ParentViewController:0x8d24bb0 >

這裏的問題是調用回調方法。該程序將達到Common.m中的方法,但不能從父級調用該方法。

+0

聽起來像您需要子類化:創建超類(即UIView子類)實現所有常見的位。然後創建該類的子類,並可能覆蓋您需要自定義的方法。 'performSelector'總是有一種奇怪的氣味。或者使用公共位的類別。 – verec

+0

@selector()是創建SEL對象的文字。既然你傳遞了一個SEL,你不需要用@selector()來包裝這個參數,你可以直接使用它。 –

回答

2

的問題是,

@selector(selector) 

搜索名爲法 「選擇。」 @selector()檢索包含在括號內的名稱的選擇器。

你想要的是使用傳入的選擇器,而不是檢索不同的選擇器。您可以通過在傳遞到選擇的方法,你會任何其他變量做到這一點:

+(void)target:(Class)object method:(SEL)selector 
{ 
    NSLog(@"target..."); 
    if ([object respondsToSelector:selector]) 
    { 
     [object performSelector:selector]; 
    } else { 
     NSLog(@"%@", object); 
    } 
} 

當使用ARC,這將導致一個警告,因爲ARC系統將無法告知發生了什麼事情。爲了通知編譯器您有意打電話給performSelector:,並確信沒有泄漏,您可以關閉這一行的警告。 只有當你確信沒有泄漏時才能做到這一點。

#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Warc-performSelector-leaks" 
      [object performSelector:selector]; 
#pragma clang diagnostic pop 

最後,讓我們來看看你的選擇,callbackMethod

+(void)callbackMethod 
{ 
    NSLog(@"Should come here..."); 
} 

這是一個類的方法,而不是一個實例方法,因此類的你實例並沒有選擇迴應,而本身。將其從類方法更改爲實例方法(通過將'+'替換爲' - ')將修復此問題:

-(void)callbackMethod 
{ 
    NSLog(@"Should come here..."); 
} 
+0

得到以下警告:_PerformSelector可能導致泄漏,因爲它的選擇器是unknown_。除了警告之外,它仍然不會進入回調方法。任何其他想法? – Sietse

+1

in' - doSomething'你傳遞了'self',它指向* instance *。然而在'+ target'中,你將參數記錄爲'(Class)',而不是'(id)'。事實證明,你似乎想發送一個實例方法選擇器作爲類方法選擇器:'+ callbackMethod'是_class_方法,而不是_instance_方法。但是,這整個代碼真的聞起來... – verec

+0

我錯過了這些問題,我已經更新了答案。我也同意@verec,如果這是用於試驗ObjC功能的代碼,那麼你很好,但如果這是爲了生產代碼,那麼它很臭。有太多的間接層需要重構。 – BergQuester

相關問題