development

Objective-C 프로토콜 전달 선언

big-blog 2021. 1. 6. 20:43
반응형

Objective-C 프로토콜 전달 선언


ObjectProperties.h

@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;

위의 코드 예제에서 Core Data 객체와 일반 ol 'vanilla 객체 모두에 사용할 프로토콜을 .h 파일에 정의했습니다. 준수하는 클래스를 갖는 것은 "노이즈"인 것 같습니다. #import the protocol in the header; 위에서 본 것처럼 구현 파일에서 프로토콜 및 가져 오기를 전달하는 것이 더 깨끗할 것입니다. 그러나 Xcode는 다음과 같이 할 때 경고를 표시합니다.

Cannot find protocol definition for 'ObjectProperties'

코드가 컴파일되고 대부분 작동합니다. 저는 주로 Core Data가 스칼라 속성에 대한 getter / setter를 동적으로 생성하려고하는 약간의 펑키함이 있기 때문에 말하지만, 아마도 엣지 케이스에 부딪 혔기 때문이라고 생각합니다.

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

내 이해가 정확하고 내 지식이 최근에 습득되었으므로 내가 틀렸을 가능성이 전적으로 가능하다면 프로토콜을 클래스 헤더로 가져 와서 프로토콜을 변경하면 내 클래스를 다시 컴파일해야합니다.

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


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

#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

Yes you are correct that all of the files will need to be recompiled, but this is necessary. Files that import the class header need to know the methods associated with the protocol it implements. If you tuck that definition away in the .m file then it is only visible to one file (since .m files never get imported). It's not the same as forward declaring classes. If you forward declare a protocol, you must declare it somewhere that is visible in the same scope as the forward declaration. I can't think of any example where this doesn't occur in the same file.

In ARC this is an error, because ARC needs to know about the memory management of the declared methods (do they return +1 instances, internal pointers, etc?)


By declaring your class in MyClass.h, you have to import all header files for its superclass as well as protocols it adopted in the MyClass.h file. Protocols in Objective-c is considered as a variant type of inheritance.

Forward declarations are usually used in class' member declaration .


Since you're declaring conformance to the protocol, you should #import the header containing the protocol.

This is the same as #importing a superclass, rather than forward declaring it:

@class Foo;

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

ReferenceURL : https://stackoverflow.com/questions/11532888/objective-c-protocol-forward-declarations

반응형