2012-07-18 3 views
51

ObjectProperties.h오브젝티브 C 프로토콜 전달 선언

@protocol ObjectProperties <NSObject> 

@property (strong, nonatomic) NSString *name; 
@property (strong, nonatomic) NSDate *date; 
@property (assign, nonatomic) int64_t index; 

@end 

ClassA.h

#import <Foundation/Foundation.h> 

@protocol ObjectProperties; 

@interface ClassA : NSObject <ObjectProperties> 

- (void)specialSauce; 

@end; 

ManagedClassA.h

#import <CoreData/CoreData.h> 

@protocol ObjectProperties; 

@interface ManagedClassA : NSManagedObject <ObjectProperties> 

- (void)doSomething; 

@end; 

위의 코드 예제에서 .h 파일의 프로토콜을 코어 데이터 객체와 일반 ol '바닐라 객체 모두와 함께 사용하도록 정의했습니다. 그것은 "노이즈"같은 준수 클래스를 가지고 # 헤더 프로토콜에서 가져 오기; 위에 표시된 것처럼 구현 파일에서 & 프로토콜 가져 오기를 전달하는 것이 더 깨끗합니다. 그러나이 방법을 수행 할 때, 엑스 코드는 경고를 발생 :

Cannot find protocol definition for 'ObjectProperties'

코드는 컴파일하고 대부분 작동합니다. 코어 데이터가 스칼라 속성에 대한 getters/setter를 동적으로 만들려고 할 때 약간의 어색함이 있기 때문에 주로 말합니다. 그러나 나는 이것이 가장자리의 경우를 맞았 기 때문에 가능하다고 생각합니다.

물론 가장 확실한 해결 방법은 프로토콜 헤더를 클래스 헤더로 가져 오는 것입니다.

내 이해가 정확하다면 (그리고 내 지식이 매우 최근에 획득되어서 내가 틀렸을 수도 있습니다.), 프로토콜을 클래스 헤더로 가져 와서 프로토콜을 변경하면 모든 후속 내 클래스를 가져 오는 파일은 다시 컴파일해야합니다.

이 유형의 문제를 해결하는 올바른 방법은 무엇입니까?

+0

비슷한 문제가 있지만 신속한 프로토콜이 있습니다. – Alper

답변

93

당신은 앞으로 슈퍼하거나 준수하는 프로토콜을 선언 할 수 없습니다. 이 경우 헤더를 포함해야합니다.이는 (수퍼 클래스의 경우) 수퍼 클래스의 인스턴스 변수와 메소드가 클래스의 일부가되기 때문입니다. (프로토콜의 경우) 프로토콜의 메소드는 명시 적으로 선언 할 필요없이 클래스에서 선언 된 메소드가됩니다. (즉, 클래스 헤더를 포함하는 다른 사람들은 자신이 선언 한 것처럼 클래스가 클래스를 선언한다는 것을 알게 될 것입니다.) 가능할 수있는 유일한 방법은 이미이 범위에서 정의 된 경우, 즉 헤더를 가져 오는 것입니다 .

#import <SomeClass.h> 
#import <SomeProtocol.h> // these two must be imported 

@interface MyClass : SomeClass <SomeProtocol> 
@end 

전달 선언은 변수 유형 (구체적으로 객체 포인터 변수)에 나타나는 항목에 유용합니다. 오브젝트 포인터는 모두 같은 크기이며 런타임에 오브젝트 포인터의 다른 유형간에 차이가 없습니다 (오브젝트 포인터 유형의 개념은 단지 컴파일 타임입니다). 따라서 이러한 유형의 클래스에 무엇이 있는지 정확히 알 필요가 없습니다. 따라서 그들은 앞으로 선언 될 수 있습니다.

@class SomeClass; 
@protocol SomeProtocol; // you can forward-declare these 

@interface MyClass { 
    SomeClass *var1; 
    id<SomeProtocol> var2; 
} 
@end 
4

예 모든 파일을 다시 컴파일해야하지만이 작업이 필요합니다. 클래스 헤더를 가져 오는 파일은 구현 된 프로토콜과 연관된 메소드를 알아야합니다. .m 파일에 정의를 저장하지 않으면 .m 파일을 가져올 수 없으므로 하나의 파일에서만 볼 수 있습니다. 앞으로 선언하는 클래스와 같지 않습니다. 프로토콜을 선언하는 경우, 전달 선언과 동일한 범위에 표시되는 어딘가에 선언해야합니다. 이 파일이 같은 파일에서 발생하지 않는 예제는 생각할 수 없습니다. ARC가 선언 된 방법의 메모리 관리에 대해 알 필요가 있기 때문에 ARC에서

이이 오류가 (그들은 한 경우, 내부 포인터를 반환 할 등?)

2

을에서 MyClass.h에 클래스를 선언함으로써 MyClass.h 파일에서 채택한 프로토콜뿐만 아니라 슈퍼 클래스의 모든 헤더 파일을 가져와야합니다. Objective-c의 프로토콜은 상속의 변형 유형으로 간주됩니다.

전달 선언은 일반적으로 클래스 '멤버 선언에 사용됩니다.

1

프로토콜에 대한 준수를 선언 했으므로 # 프로토콜을 포함하는 헤더를 가져와야합니다.

이 그것을 선언 앞으로 슈퍼 클래스를 #importing보다는과 동일합니다 :

@class Foo; 

@interface Bar : Foo 
// Will get error: attempting to use the forward class 'Foo' as superclass of 'Bar' 
@end;