2014-02-19 2 views
8
Class bah = [NSString class]; 

id object = [bah new]; 

컴파일해도 전혀 문제가 없습니다.Objective-C 런타임 : 프로토콜 의미를 준수하는 Class (objc_class) 유형의 변수를 선언하는 것은 무엇입니까?

Class<NSSecureCoding> bah = [NSString class]; 

id object = [bah new]; 

"선택기 '새'에 대한 알려진 클래스 메서드가 없습니다. '오류를 반환합니다.

첫 번째 인스턴스가 NSObject에 정의 된 +new 메서드를 호출 할 수 있지만 두 번째 인스턴스는 호출 할 수 없다는 것을 이해하는 이유는 무엇입니까? 애플의 문서에 따르면

답변

5

:

Protocols can’t be used to type class objects. Only instances can be statically typed to a protocol, just as only instances can be statically typed to a class. (However, at runtime, both classes and instances respond to a conformsToProtocol: message.)

이 오래된 문서에서이지만, 이후 변경되었음을 말하는 아무것도 없다. 그러나 그것이 여전히 유효하다고 가정 할 때, 당신은 당신이하는 일을해서는 안됩니다. NSString의 인스턴스는 해당 프로토콜을 준수 할 수 있지만 NSStringClass 개체가이를 준수한다고 말하는 것은 아닙니다.

왜 오류가 발생했는지에 관해서는 프로토콜을 지정할 때 해당 프로토콜에없는 메서드에 대한 오류를보고하기 때문에 오류라고 생각합니다. 예를 들어, 다음 오류 제공합니다

Class<NSSecureCoding> bah = [NSString class]; 
id object = [bah class]; 

을하지만 (이 class는 인스턴스 메서드가 아닌 클래스 메소드하다는 경고를 제공하지만) 다음은 컴파일 : 또한

Class<NSObject> bah = [NSString class]; 
id object = [bah class]; 

당신이 ' NSObject 프로토콜에 new이 정의되어 있지 않으며, NSObject 클래스에만 정의되어 있습니다.

Class을 지정하면 컴파일러에서 정확한 유형을 알 수 없다는 점에서 id을 지정할 때와 비슷한 작업을 수행하므로 알려진 유형의 메소드를 호출 할 수 있습니다. 그러나 프로토콜을 추가하면 해당 프로토콜에서 메소드를 호출 할 수있게됩니다.

if ([bah conformsToProtocol:@protocol(NSSecureCoding)]) 
+3

그리고 이것은 당신이 말하는 레거시 문서에 대한 링크입니다 : [객체 지향 프로그래밍 및 Objective-C 프로그래밍 언어 1.0] (https://developer.apple.com/legacy/library/documentation/Cocoa /Conceptual/OOPandObjC1/OOPandObjC1.pdf), 62 페이지. (내 대답은 거의 끝났습니다 :-) –

+1

@MartinR 설명서 링크를 제공해 주셔서 감사합니다. – Gavin

+2

그리고 btw,'Class = [NSString class]'는 * any * 프로토콜에 대한 경고없이 컴파일합니다. - http://lists.cs.uiuc.edu/pipermail/llvmbugs/2013-March/027464.html을 참조하십시오. –

1

Class<NSSecureCoding> 프로토콜의 클래스 메소드에 응답하는 오브젝트입니다 : 당신은 그냥 Class를 사용하는 동안 특정 프로토콜을 준수 bah에 할당 무엇을 확인하려면

, 당신은 다음을 사용할 수 있습니다 NSSecureCoding. 프로토콜 NSSecureCoding은 메서드 +new을 선언하지 않으므로 호출 할 수 없습니다.