2011-08-31 121 views
5

我有一個小問題,就是把我拉上了牆。我在寫一個應用程序時將代碼作爲模式使用。我試圖在調用代理的代碼中儘可能「小心」,因爲我可以通過在每個委託調用上使用「[delegate respondsToSelector]」來測試委託。一切工作正常,除非我在UIView子類。在這種情況下,respondsToSelector返回NO,但我可以安全地調用委託代碼,以便它存在並正常工作。爲什麼在這種情況下,respondsToSelector不適用於我?

我把它煮成了我可以在下面的最簡單的例子。您可以提供任何幫助,將不勝感激:

裏面我UIView子類的.h文件中的:

#import <UIKit/UIKit.h> 

@protocol TestDelegate <NSObject> 
@optional 
-(double)GetLineWidth; 
@end 

@interface ViewSubclass : UIView { 
    id<TestDelegate> delegate; 
} 

@property (nonatomic, retain) id<TestDelegate> delegate; 

@end 

在我的委託類的.h文件中:

#import <Foundation/Foundation.h> 
#import "ViewSubclass.h" 

@interface ViewDelegate : NSObject <TestDelegate> { 

} 

@end 

在我的委託類的.M文件:

#import "ViewDelegate.h" 

@implementation ViewDelegate 

-(double)GetLineWidth { 
    return 25.0; 
} 

@end 

在我的UIView子類的.m文件中:

- (void)drawRect:(CGRect)rect 
{ 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    double lineWidth = 2.0; 

    if (delegate == nil) { 
     ViewDelegate *vd = [[ViewDelegate alloc]init]; 
     delegate = vd; 
    } 

    // If I comment out the "if" statement and just call the delegate 
    // delegate directly, the call works! 
    if ([delegate respondsToSelector:@selector(GetLineWidth:)]) { 
     lineWidth = [delegate GetLineWidth]; 
    } 

    CGContextSetLineWidth(context, lineWidth); 
+0

通常你不會希望保留代表'@財產(非原子,分配)ID 委託;' – slf

+1

什麼羅布說;該方法應該被稱爲'lineWidth'。方法不應該以大寫字母開頭,並且應該只在極少數情況下以'get'開始。這不是一種風格選擇,這是一種模式,您必須遵循框架的所有功能才能正常工作。 – bbum

回答

14

-(double)GetLineWidth的選擇器是@selector(GetLineWidth)

你的選擇器中有一個額外的冒號。

if ([delegate respondsToSelector:@selector(GetLineWidth:)]) { 
                ^
+0

好吧,你是第一個=) – Nekto

+5

並將'GetLineWidth'重命名爲'lineWidth'。不要使用「獲取」優先訪問器,並且不要以大寫字母開頭。它在Cocoa中很重要,它不僅僅是一種風格選擇。 –

+0

Doh!感謝大家! – user704315

3

更換if語句這一個:

if ([delegate respondsToSelector:@selector(GetLineWidth)]) { 
    lineWidth = [delegate GetLineWidth]; 
} 
相關問題