2015-01-22 3 views
3

내 클래스에는 id 유형 매개 변수를 취하고 해당 객체에서 일부 연산을 수행하는 -aMethod: 메소드가 있습니다. 이제 그 객체의 -someMethod을 호출하는 메소드를 호출하려고합니다. 하지만 문제는 객체 유형이 id이며 어떤 유형의 객체가 여기에 올지 알 수 없으므로이를 캐스팅 할 수 없습니다. 아래 코드는 내 코드 no know instant method for the selector someMethod입니다. 어떤 종류의 신체라도 그러한 유형의 상황을 처리 할 수 ​​있습니까?respondsToSelector from id type 객체

차단 또는 위임을 사용하고 싶지 않습니다.

- (void)aMethod:(id)anObject 
{ 
    // other stuff 
    if([anObject respondsToSelector:@selector(someMethod)]) [anObject someMethod]; 
} 

enter image description here

답변

7

당신은 단순히 컴파일러에게 어떤 식 으로든 보여줘야합니다. 그런 식으로 수신기를 입력 할 필요가 없습니다. (하지만 그렇게 할 것입니다.) 개인적으로 나는 방법을 수집하는 프로토콜을 선호합니다.

@protocol MyDelegateProtocol 
- (void)someMethod; 
@end 

// You do not have to use that protocol for typing. 
// So you can use your code as you did. 

또 다른 방법은 클래스에 카테고리를 추가하는 것입니다.

@interface AnyClassIncludingNSObject(MyDelegateAddition) 
- (void)someMethod; 
@end 

하지 그 범주를 구현 마십시오.

세 번째 해결 방법은 메시지를 보내는 클래스에 메서드를 추가하는 것입니다.

- (void)someMethod {} 

항상 동일합니다. 컴파일러는 한 번만 확인해야합니다. 어떤 이유로 당신이 프로토콜을 선언하지 않으려면

, 당신이 이런 식으로 작업을 수행 할 수 있습니다 : 여기에 다른 답변에 추가

+0

답변 해 주셔서 감사합니다. 제 3의 솔루션이 나의 요구 사항을 충족합니다. –

2

당신은 당신이 프로토콜을 만들어야 전송됩니다 정확한 클래스 유형을 알고 및 전송 (어느 대상 메소드를 구현) 할 수있는 모든 클래스가없는 경우에 확인 그 프로토콜. 이제 캐스팅 (또는에 전달 된 매개 변수를 설정) id <MyProtocol> 및 컴파일러가 행복 할 것입니다.

+0

위임자 또는 차단자가 해결할 수 있음을 알고 있었지만이를 원하지 않습니다. –

+1

그럴 필요가 없습니다. 컴파일러는 어쨌든 메서드를보고 싶을뿐입니다. –

+0

@ TapasPal : 좋은 충고는 무시하고 자유롭게 행동하십시오. – gnasher729

0

요구 사항 유형 인 NSObject의 하위 클래스를 만듭니다. 귀하의 경우 AnObject.

이제이 클래스에 someMethod을 구현 한 다음 id 대신이 클래스를 매개 변수로 사용하십시오.

someMethod을 원하는대로 호출하여 구현할 수 있습니다.

0

는 당신이 필요로하는 경우

if ([anObject respondsToSelector:@selector(someMethod)]) { 
    [anObject performSelector:@selector(someMethod)]; 
} 

performSelector:withObject:있다 인수를 전달하려면 performSelectorOnMainThread 및 기타.

+0

하지만 여전히 경고입니다. '선언되지 않은 선택기 someMethod' –

+0

@TapasPal, 죄송합니다. 주된 문제점은'알려진 인스턴스 메소드 없음 '오류라고 생각했습니다. 그래도 누군가가 유용하다고 생각하기 때문에 대답을 남겨 둘 것입니다. – FreeNickname

1

내가 알기로 다른 사람들이 제안한대로 올바른 방법을 사용하고 싶지는 않습니다.

#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Wundeclared-selector" 

... your code here ... 

#pragma clang diagnostic pop 

그냥 #pragma의 사이에 코드를 이동 : 그래서,이 문제를 해결하기 위해, 내가 먼저 경고를 제거하는 것입니다.

두 번째로 someMethod이 선언 된 클래스를 #import으로 지정하고 메서드를 호출 할 때 해당 클래스에 '알 수 없음'개체를 캐스팅합니다. 좋아요 : [(MySuperClassThatHasSomeMethodDeclared *)anObject someMethod];

그리고 걱정하지 마십시오. 전달한 객체에 someMethod이 호출됩니다.

그래서 여기에 문제를 해결하는 방법이 있습니다. 행운을 빕니다!

+0

질문을 게시하기 전에'protocol'을 사용하여이 상황을 이미 해결했습니다. 그래서 '블록 또는 위임자'를 사용하지 않고 내 질문에 언급합니다. 나는 다른 방법이 있다면 그것을 알고 싶었습니다. 다른 솔루션을 아는 것은 나쁜 습관입니까? –

+0

그런 다음 질문에 언급해야합니다. 귀하의 질문에, 당신은 문제를 해결할 수없는 가장 가난한 사람처럼 보이지만, 당신은 옳은 대답을 무시하고 계속, 그래서 내가 이렇게 대답했습니다. –