2011-12-05 4 views
12

클래스 디버깅에 도움이 필요합니다. 나는 비슷한 것을 찾을 수 없을 정도로 기괴한 오류가 발생했습니다. 그래서 나는 대부분 내 코드를 내려 놓을 것입니다.Xcode 오류 : 선택기에 알려진 인스턴스 메서드가 없습니다.

//Tab.h 
#import <UIKit/UIKit.h> 
@class Tab; 
@protocol TabDelegateDataSource <NSObject> 
@required 
-(void)removeTab:(Tab *)tab; 
@end 

@interface Tab : UIView 
{ 
    id <TabDelegateDataSource> __strong _delegate; 
} 

@property(strong) id <TabDelegateDataSource> delegate; 

-(void)removeTab; 

@end 

// Tab.m 
#import "Tab.h" 
@implementation Tab 
@synthesize delegate = _delegate; 
-(void)removeTab 
{ 
    [self.delegate removeTab:self];//Error here saying: No known instance method for selector 'removeTab:' 
} 

@end 
+1

이것을 잊지 마세요, 무엇을 'self.delegate'를'_delegate'로 바꾸면 문제가 발생할 수 있습니다. – dasblinkenlight

+0

당신의 델리게이트는 실제로'removeTab' 메소드를 가지고 있습니까? 이 오류 메시지는 그렇지 않음을 의미합니다. 디버그와 self.delegate 검사를 해보고 기대했던대로하고 removeTab 메소드를 가지고 있는지 확인하십시오. – WilHall

+1

게시 한 코드에 문제가 없습니다. 새 프로젝트에 복사하고 오류 및 경고없이 컴파일합니다. –

답변

5

나는 그것이 Xcode로 어리석은 문제라고 생각한다. 나는 앱을 몇 번 재시작했는데, 문제가 해결되었다.

+0

이 답변을 해결할 수는 없지만 Xcode를 다시 시작하면 문제가 해결됩니다. 고마워. – PhatHV

4

당신은 항상도 필요한 프로토콜 방법과, 메소드를 호출하기 전에 대리인이 방법을 확인해야합니다 :이 검사이기 때문에, 심지어 필요한 방법에 대해 이렇게

if(self.delegate != nil && [ self.delegate respondsToSelector: @selector(removeTab:) ] 
{ 
    /* Call delegate method... */ 
} 

여분의 안전을 추가 런타임시 작성.
누군가는 컴파일러 경고를 무시하거나 비활성화하거나 컴파일러를 타입 캐스트로 속일 수 있습니다. 예를 들어

: 또한

UILabel * label  = [ [ UILabel alloc ] initWithFrame: CGRectZero ]; 
someTableView.delegate = (id <UITableViewDelegate>)label; 

, 당신은 실제 메서드 호출에 대한 performSelector을 사용할 수 있습니다 :

[ self.delegate performSelector: @selector(removeTab:) withObject: self ]; 
+6

프로토콜에서 요구되는대로 정의 된 메소드에 이것이 필요한 이유는 알 수 없습니다. 컴파일러는 필요한 메소드가 구현되지 않은 경우 경고를 표시합니다. –

+1

@Macmade 메소드 호출을 통해'performSelector'를 선호하는 이유는 무엇입니까? – zaph

+0

@fluchtpunkt 이것은 매우 안전하므로 컴파일러 설정에 의존하지 않습니다. 런타임 검사의 이유를 설명하는 내 편집을 참조하십시오. – Macmade

1

시도가 delegateForTab처럼 다른 사람에게 delegate의 이름을 변경 할 수 있습니다. TabUIView의 서브 클래스입니다

클래스, 그래서 self.delegateself 클래스는 UIView의 서브 클래스입니다. UIView은 자신의 델리게이트 (UIResponder에서 상속 받았으며 NSObject에서 깊이 상속받은)를 가질 수 있으며 -(void)removeTab 메서드가 없습니다. 내 개인적인 추측.
내 솔루션은의 이름을 (아직 서브 클래 싱 할 수 있는지 여부는 알 수 없음)으로 변경합니다. 대표를 사용하는

제안 : 당신은 를 구현하지 당신이 그것을 선언 같은 클래스에서 다른 뷰 컨트롤러에 delegate를 사용해야합니다. :)

+0

좋은 방법이지만 UIView에는 대리인이 없습니다. 그래서 이것은 불행하게도 도움이되지 않을 것입니다 ... :) – Macmade

+0

@Macmade, 조언 해 주셔서 감사합니다!나는이 문제를 전에 만난 적이있다. UINavigationController에서 상속받은 클래스를 만들었고, 같은 오류가 발생했다. 나는 위임자의 이름을 변경하여이를 해결했다. 지금은 SDK를 참조하고 UIView에는 델리게이트가 없습니다. :) 그러나, 그것은'UIResponder'에서 상속 받았고'NSObject'에서 깊은 상처를 받았습니다. 'NSObject'는 프로토콜과 델리게이트를 가지고 있습니다. 그래서 저는'[self.delegate removeTab : self];''self'는 단지 NSObject 일 뿐이라고 생각합니다. 이것이 진정한 이유인지 여부는 확실하지 않습니다. 내 개인적인 추측. : p – Kjuly

0

이 오류는 컴파일러 오류가 아닙니다. 그렇지 않습니까? 왜냐하면 여기에 당신의 코드에 컴파일러 에러가 없기 때문입니다. 이 런타임 오류 인 경우

그래서,이 같은 대리자 클래스에서 <TabDelegateDataSource> 선언이 : 인스턴스 메소드가 할 수없는 경우에 당신이 그렇게하면

@interface SomeClass : UIView <TabDelegateDataSource>

를, 컴파일러는 경고한다 찾을 수 있습니다.

또는 더 많은 정보를 원하시면 위임자 클래스의 코드를 게시해야합니다.

P. 대의원은 __strong이 아니어야합니다. 대신 __unsafe_unretained을 사용하는 것이 좋습니다.

14

이제이 오류를 다시 만들고 수정할 수 있습니다.

는 확인이이이 정의 된 .H 헤더 ...

@protocol TabDelegateDataSource <NSObject> 
-(void)removeTab:(Tab *)tab; 
@end 

...위임을 사용하려는 경우 어디서나 이 포함되어 있습니다 (예 :). 어딘가에이 포함하는 .m 소스의 상단 :

@protocol TabDelegateDataSource; 

당신은 오류가 발생합니다 : 컴파일러는이 같은 TabDelegateDataSource의 앞으로 정의를 본 경우

[self.delegate removeTab:self] 

:

error: no known instance method for selector 'removeTab:' 

아니라 더 예상 앞으로 정의 관련 오류

+1

이것이 제 문제였습니다. 이 .h 파일에서 프로토콜 용 헤더를 가져 오지 못했습니다. 감사합니다 ! –

0

내 appdelegate.h 가져 오기 및 오류 해결 ...

2

인터페이스에서 대리자 속성을 잘못 선언하지 않았는지 확인하십시오 (다른 파일에서 복사하여 붙여 넣기 등). 예를 들어 :

@protocol SomeDelegate 

... 

@end 

@interface SomeClass 

... 

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


@end 

는 위의 라인은 "선택에 대한 알려진 인스턴스 방법을 ..."원인이되지 않습니다 때문에 indtended 프로토콜, 아마 복사 및 붙여 넣기 오류와 불일치. 또한,이 코드 행에서 멀리 떨어져 실제로 위치하는 DIFFERENT 클래스의 올바른 참조를 무시할 가능성이 높습니다.

는 수정하여 구성 프로토콜을 사용하여 속성을 선언 위 :

@property (nonatomic, retain) id<SomeDelegate>delegate; 
+0

대리인은 항상 약합니다 (절대 보유하지 않음/강함) – SamB

0

누군가가 필요 할 수

SEL selector = NSSelectorFromString(@"removeTab"); 

if([self.delegate respondsToSelector:selector]) { 
    objc_msgSend(self.delegate, selector); 
} 

참고 : 호기심, #import <objc/message.h>

관련 문제