2010-08-04 4 views
2

나는 UIView 속성을 가진 클래스가있는 프로젝트에서 작업하고 있습니다. 또한 특정 메소드를 정의하는 UIView의 서브 클래스 인 클래스를 정의합니다. 나는 다음과 같은 코드가있는 경우, 내가 빌드 할 때 경고를 얻을 :오브젝트 respondsTo가 여전히 경고를 던졌습니다

// In this example, myView is UIView property which *may* contain a UIView or 
// my subclassed-UIView which has the myMethod method 
if([myView respondsToSelector:@selector(myMethod)]){ 
    [myView myMethod] 
} 

경고 "가있는 UIView가 응답하지 않을 수 있습니다 '-myMethod'"입니다. 경고는 분명히 앱이 빌드되는 것을 멈추지는 않지만, 어떻게 처리해야 하는지를 파악하려고하고 있습니다. 이 작업을 수행하는 올바른 방법입니까? 이 경고를 중지 할 수있는 방법이 있습니까?

답변

5

경고가보기 사용자 정의 서브 클래스 인 경우 컴파일러 모르는 때문이다. 물론, 서브 클래스가 될 것이므로 런타임에는 잘 작동합니다. 당신은 그것을 해결하기 위해 두 가지 옵션이 있습니다

[myView performSelector:@selector(myMethod)]; 

(그래서 메소드의 모든 호출을 확인하지 않습니다 컴파일러)

또는 더 나은 :

[(MyViewClass *)myView myMethod]; 

그 방법 컴파일러 행위 등을 객체가 실제로 당신의 뷰 서브 클래스라면 (물론 검사를 한 후에).

그 문제에 대한

,이 방법보다는 클래스를 확인하는 의미가 있습니다

if ([myView isKindOfClass:[MyViewClass class]]) { ... 
+0

메시지가 일반적으로 더 나은 것으로 간주됩니다에 객체가 응답 여부를 확인. 수업을 요청하는 것은 코드가 귀하의 메시지에 응답 할 것인지를 물어 보는 우회 길입니다. – Chuck

+0

여기에있는 생각은 사용자 정의 하위 클래스에만 적용되는 코드를 작성하는 것입니다. 선택기에 응답하는지 여부는 관련성이 있지만 한 번에 둘 이상의 호출을 수행하는 경우 또는 코드가 예상 한대로 정확하게 수행되는지 여부를 확인하려면 클래스를 확인하면됩니다. – jtbandes

+0

수업을 확인하는 것으로도 충분하지 않습니다. 그런 다음 클래스의 버전을 확인해야합니다 (가능한 경우). 그것을 JavaScript 코드에서했던 것과 비교해 볼 때, 자바 스크립트 기능이 사용 가능한지 확인하기 위해 페이지를 보는 데 사용 된 브라우저를 확인하는 것이 좋습니다. – kiamlaluno

1

당신은 사용할 수 있습니다

[myView performSelector:@selector(myMethod)]; 
1

를이 변수로 선언 된 유형에 응답하지 않는 것을 말하고, 정적 타이핑 경고입니다 그 선택기. 실제로 셀렉터에 응답 한 하위 클래스를 사용하고 있기 때문에 이것이 문제가되지 않는다는 것을 알지만 컴파일러는이를 파악하기에 현명하지 않습니다. 이 문제를 해결할 수있는 몇 가지 방법이 있습니다. 실제로 특정 클래스 또는 프로토콜 중 하나, 선택기에 응답을 수행하는 것이 무엇인지에

  1. 캐스트 변수 : 안전의 순이었다. 여전히 적절한 헤더를 가져와야 할 것입니다. 그렇지 않으면 컴파일러가 실수로 무언가를 잘못 입력했다고 의심 할 것입니다. 상황에 따라 어떤 옵션이 가장 적합한가요 (예 : 전송할 '올바른'클래스가 있는지 등).

    [(id<SomeProtocolWiththatSelector>)myView myMethod]; 
    [(SomeUIViewSubclass *)myView myMethod]; 
    
  2. id 전송하는 변수 정적 유형 검사를 중지한다. 컴파일러에서 일부 메서드가 존재한다는 것을 알기 위해 선언문이있는 머리글을 가져와야합니다. 그렇지 않으면 "이것이 실제 메서드인지 확실하지 않습니다."라는 경고가 표시됩니다.

    [(id)myView myMethod]; 
    
  3. performSelector:을 사용하십시오. 컴파일시에는 검사를하지 않으므로 Foundation 외에 다른 헤더를 가져올 필요가 없지만 컴파일러는 오타를 발견하지 못하기 때문에 실수로 인해 프로그램이 런타임에 붐을 일으킨다는 것을 의미합니다.

    [myView performSelector:@selector(myMethod)]; 
    
관련 문제