2011-08-31 2 views
5

나는 벽 위로 나를 몰고있는 작은 수수께끼를 가지고있다. 나는 위임을 내가 쓰고있는 응용 프로그램의 패턴으로 꽤 많이 사용하고있다. 나는 "delegate respondsToSelector"를 사용하여 각 위임 된 호출에서 위임을 테스트하여 위임을 호출하는 코드에서 "주의"가되도록 노력하고 있습니다. 내가 UIView 하위 클래스에 없으면 모든 것이 잘 작동합니다. 이 경우 responsToSelector는 NO를 반환하지만 위임 코드를 안전하게 호출하여 올바르게 존재하고 올바르게 작동 할 수 있습니다.왜이 경우 respondsToSelector가 작동하지 않습니까?

나는 아래에있는 가장 간단한 예제로 그것을 끓여 놨다. 당신이 제공 할 수있는 모든 도움을 주시면 감사하겠습니다 :

내 UIView 하위의 .H 파일의 내부

: 내 대표 클래스의하는 .m 내부

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

@interface ViewDelegate : NSObject <TestDelegate> { 

} 

@end 

: 내 대표 클래스의 .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 

파일 : 내 UIView 하위의하는 .m 파일 내부

#import "ViewDelegate.h" 

@implementation ViewDelegate 

-(double)GetLineWidth { 
    return 25.0; 
} 

@end 

:

- (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'로 개명하십시오. "Get"이있는 접근자를 선호하지 말고 선행 캡으로 시작하지 마십시오. 그것은 코코아에서 중요합니다. 그것은 단지 스타일 선택이 아닙니다. –

+0

Doh! 모두에게 감사드립니다! – user704315

3

경우 문이 하나 교체 : 당신이 대표`@property를 유지하고 싶지 않아요

일반적으로
if ([delegate respondsToSelector:@selector(GetLineWidth)]) { 
    lineWidth = [delegate GetLineWidth]; 
} 
관련 문제