2014-01-29 1 views
3

ARC가 메서드 서명 정보를 가져 오는 위치를 파악하려고합니다. 다음 코드에서이 클래스의 클래스를 지정하지 않고이 객체의 부모에게 메시지를 보냅니다. 상위 ivar을 타입 변환하지 않으면 컴파일러에서 경고를 표시합니다. ID로 형식 변환하면 프로그램이 작동하고 경고가 표시되지 않습니다. 부모의 방법은 userSelected:에 다른 경우 내가 (경고를 발행하면서) 다음 를 작동하는 유일한 것은 performSelector입니다 performSelector:withObject:ARC 및 컴파일 타임에 클래스를 지정하지 않고 개체에 메시지 보내기

를 사용하는 경우에도 마찬가지 입니다.

알다시피, ARC는 self.parent에 대한 호출이 객체에서 메소드 서명을 받고 있습니다. 이 올바른지? 메시지가 전송되는 객체에 메서드 시그니처가 있으면 객체가 어떤 클래스인지 ARC에 알리지 못합니까?

- (void)userSelected:(id)sender 
{ 
    if ([self.parent respondsToSelector:@selector(userSelected:)]) { 

     //1: This fails with error (no visible interface). 
     [self.parent userSelected:self]; 
     //2: This line works without warnings. 
     [(id)self.parent userSelected:self]; 
     //3: This line also works 
     [self.parent performSelector:@selector(userSelected:) 
          withObject:self]; 
} 
+1

경고 메시지가 표시됩니다. –

답변

2

Wil Shipley는 삭제 된 답변에서 ARC와 관련이 없다고 말하면 정확합니다.

받는 사람의 정적 유형 (self.parent) 및이 선택기에 응답하지 않는 개체로 메시지를 보내지 못하도록하는 컴파일러에 대한 경고가 표시됩니다. 즉, self.parent의 클래스에 userSelected:이라는 선언이 없습니다.

그러나 정적 유형 정보없이이 메시지를 보낼 수 있기 때문에 컴파일러는 userSelected: (다른 클래스 또는 범주에서) 메서드를 알고 있습니다. C 언어와 마찬가지로 포인터의 유형에 상관없이 void 포인터를 사용할 수 있습니다.

다시 말해서 모든 것은 ARC와 관련이 없으며 MRC로 전환 할 때 변경되지 않습니다.

편집 :

id에 메시지를 보낼 때 예, 컴파일러는 선택의 선언을 찾기 위해 눈에 보이는 @interface와 @protocol을 고려합니다. 이 경우의 '표시'는 가져온 헤더를 의미하며 맞춤 헤더, 프레임 워크 또는 접두사가 될 수 있습니다. 메소드 선언은 주로 매개 변수의 유형 정보를 얻는 데 필요합니다.

매우 희귀 한 시나리오 (선언문에 objc_method_family 등의 소유권 의미에 대한 정보가 포함되어있는 경우)에서만 ARC 동작이 영향을받습니다.

컴파일러가 충돌하는 선언을 발견하면 오류가 발생합니다. 컴파일하려고 할 때 ...

[(id)nil type]; 

... 당신이 ...

> error: multiple methods named 'type' found with mismatched result, parameter type or attributes 

을 얻을 ... 플러스 UIKit, 재단과 다른 프레임 워크에서 다른 선언의 몇 가지 있습니다.

+0

하지만 self.parent에서 호출되는 메서드가 userSelected 인 경우 경고 또는 실패가 발생하지 않습니다. 그것은 올바르게 작동합니다. 그래서 내 질문은 : 컴파일러가 기존 파일뿐만 아니라 적절한 클래스 파일 (self.parent에 대한)에서 메서드 서명을 찾습니까? ARC (또는 컴파일러)가 모든 프로젝트 파일에서 선택기를 찾을 수 있습니까?이 파일의 메소드는 동일한 선택 자이지만 다른 매개 변수를 가졌을 것입니다. – theprole

+0

@theprole 편집을 참조하십시오. –