문제

Objective-C에서는 카테고리를 사용하여 기존 클래스에 메소드를 추가 할 수 있습니다.

@interface NSString (MyCategory)
- (BOOL) startsWith: (NSString*) prefix;
@end

NSString 프로토콜이있는 경우 프로토콜을 사용 하여이 작업을 수행 할 수도 있습니다.

@interface <NSString> (MyCategory)
- (BOOL) startsWith: (NSString*) prefix;
@end

공개 nsobject 메소드 만 사용하여 nsobject (클래스)에 대한 몇 가지 확장 기능이 있으므로이 작업을 수행하고 싶습니다. 이러한 확장자는 프로토콜을 구현하는 객체와 작동하기를 원합니다.

추가 예를 들어, 객체의 설명을 로그에 인쇄하는 메소드 로그 데 스크립 션을 작성하려면 어떻게해야합니까?

- (void) logDescription {
    NSLog(@"%@", [self description]);
}

물론이 방법을 nsobject에 추가 할 수는 있지만 nsobject에서 상속되지 않는 다른 클래스가 있습니다. 예를 들어 NSPROXY 도이 방법을 갖고 싶습니다. 이 방법은 프로토콜의 공개 멤버 만 사용하므로 프로토콜에 추가하는 것이 가장 좋습니다.

편집 : Java 8은 이제 인터페이스에 "가상 확장 메소드"가 있습니다. http://cr.openjdk.java.net/~briangoetz/lambda/defender%20methods%20v4.pdf. 이것이 바로 객관적인 c에서하고 싶은 일입니다. 이 질문 이이 많은 관심을 얻지 못했습니다 ...

안부, Jochen

도움이 되었습니까?

해결책

Extobjc는 가장 깔끔한 것들을 가지고 있습니다 당신은 프로토콜 / 카테고리로 할 수 있습니다 ... 우선 꺼짐은 @concreteprotocol...

  • 프로토콜 내에서 메소드의 기본 구현을 제공 할 수있는 "콘크리트 프로토콜"을 정의합니다.
  • an @protocol 블록은 헤더 파일에 존재해야하며 해당하는 @concreteprotocol 구현 파일의 차단.
  • 이 프로토콜을 준수하도록 선언하는 모든 객체는 메소드 구현을 수신하지만 동일한 이름의 메소드가 이미 존재하지 않는 경우에만 가능합니다.

myProtocol.h

@protocol MyProtocol 
@required - (void)someRequiredMethod;
@optional - (void)someOptionalMethod;
@concrete - (BOOL)isConcrete;   

myProtocol.m

 @concreteprotocol(MyProtocol) - (BOOL)isConcrete { return YES; } ...

그래서 대상을 선언합니다 MyDumbObject : NSObject <MyProtocol> 자동으로 반환됩니다 YES 에게 isConcrete.

또한 그들은 가지고 있습니다 pcategoryinterface(PROTOCOL,CATEGORY) "프로토콜 프로토콜에서 카테고리라는 범주의 인터페이스를 정의합니다". 프로토콜 범주에는 프로토콜을 준수하도록 선언하는 클래스에 자동으로 적용되는 메소드가 포함되어 있습니다. "구현 파일에 사용해야하는 매크로가 포함되어 있습니다. 문서를 참조하십시오.

마지막으로, 최소한 / 아님 곧장 ~와 연관되다 @protocols ~이다synthesizeAssociation(CLASS, PROPERTY), "관련 객체를 사용하는 클래스의 속성을 합성합니다. 이는 주로 카테고리 내의 클래스에 속성을 추가하는 데 유용합니다. 속성은 다음과 같습니다. @property 지정된 클래스 (또는 그 범주)의 인터페이스에서 객체 유형이어야합니다. "

너무 많은 이 라이브러리의 도구 중 하나는 여러 상속에서 OBJC로 할 수있는 일이 열려 있습니다.

다른 팁

짧은 대답 : 아니요.

긴 대답 :이게 어떻게 작동할까요? 당신을 상상해보십시오 ~할 수 있었다 기존 프로토콜에 메소드를 추가 하시겠습니까? 이게 어떻게 작동할까요? NSCoding에 다른 방법을 추가하고 싶다고 상상해보십시오. -(NSArray *) codingKeys; 이 방법은 객체를 인코딩하는 데 사용되는 키 배열을 반환하는 필수 메소드입니다.

문제는 이미 NSCoding을 구현하는 기존 클래스 (예 : NSString)가 있지만 구현하지 않는다는 것입니다. codingKeys 방법. 어떻게해야합니까? 사전 컴파일 된 프레임 워크가 어떻게 해야하는지 어떻게 알 수 있습니까? 필수의 메시지를 구현하지 않는 클래스로 메시지가 전송됩니까?

"카테고리를 통해이 방법의 정의를 추가 할 수 있습니다"또는 "이러한 프로토콜 범주를 통해 추가 된 모든 방법이 명시 적으로 선택 사항이라고 말할 수 있습니다"라고 말할 수 있습니다. 예, 당신은 이것을 할 수 있고 이론적으로 위에서 설명한 문제를 해결합니다. 그러나 그렇게한다면, 당신은 또한 처음에 카테고리로 만들 수도 있고, 수업을 확인하는지 확인하십시오. respondsToSelector: 방법을 호출하기 전에.

프로토콜에 대한 범주를 정의 할 수 없다는 것은 사실이지만 (기존 객체에 대해 아무것도 모르기 때문에 원하지 않을 것입니다), 코드가 객체에만 적용되는 방식으로 범주를 정의 할 수 있습니다. 원하는 프로토콜 (C ++의 부분 템플릿 전문화와 같은 종류)을 갖는 주어진 유형.

이와 같은 것에 대한 주요 용도는 클래스의 사용자 정의 버전에 의존하는 범주를 정의하려는 경우입니다. (FOO 프로토콜을 준수하는 UIViewController 하위 클래스가 있다고 상상해보십시오. UIViewController에게는 코드가 기본적으로 컴파일되지 않으며, 컴파일을 강요한다는 것은 내성을 수행하거나 망치는 사람이 프로토콜에 의존하는 코드를 호출 할 수 있음을 의미합니다. 하이브리드 접근 방식은 다음과 같이 작동 할 수 있습니다.

@protocol Foo
- (void)fooMethod

@property (retain) NSString *foo;
@end

@implementation UIViewController (FooCategory)

- (void)fooMethod {
    if (![self conformsToProtocol:@protocol(Foo)]) {
        return;
    }

    UIViewController<Foo> *me = (UIViewController<Foo>*) self;
    // For the rest of the method, use "me" instead of "self"
    NSLog(@"My foo property is \"%@\"", me.foo);
}
@end

하이브리드 접근 방식을 사용하면 코드를 한 번만 작성하고 (프로토콜을 구현 해야하는 클래스 당) 프로토콜을 준수하지 않는 클래스의 인스턴스에 영향을 미치지 않도록하십시오.

단점은 속성 합성/정의가 여전히 개별 서브 클래스에서 발생해야한다는 것입니다.

프로토콜이 실제로 메소드를 구현할 수 없기 때문에 그렇게하는 것은 실제로 의미가 없습니다. 프로토콜은 일부 방법을 지원한다고 선언하는 방법입니다. 프로토콜 외부 에서이 목록에 메소드를 추가한다는 것은 모든 "준수"클래스가 실수로 새로운 메소드를 구현하지 않더라도 실수로 선언한다는 것을 의미합니다. 일부 클래스가 NSObject 프로토콜을 구현했지만 NSObject에서 내려 오지 않은 다음 프로토콜에 메소드를 추가하면 클래스의 적합성을 깨뜨릴 수 있습니다.

그러나 선언과 같은 선언이 포함 된 새로운 프로토콜을 포함하는 새로운 프로토콜을 만들 수 있습니다. @protocol SpecialObject <NSObject>.

나는 당신이 여기저기서 용어를 혼합하고 있다고 생각합니다. 확장, 카테고리, 프로토콜, 인터페이스 및 클래스는 대상 C에서 모두 다른 것입니다. ~ 안에 목표 C 2.0 언어 Apple은 카테고리 및 확장 사용에 대한 이점과 단점을 포함하여 차이점을 잘 설명합니다.

당신이 그것에 대해 생각한다면, 개념적 의미에서 "범주"또는 "확장"은 무엇입니까? 클래스에 기능을 추가하는 방법입니다. Objective-C에서 프로토콜은 구현이 없도록 설계되었습니다. 따라서 처음부터 구현이없는 것의 구현을 어떻게 추가하거나 확장 하시겠습니까?

이미 카테고리를 작성하는 경우 카테고리 정의 직후 헤더에 프로토콜 정의를 추가하지 않겠습니까?

@interface NSString (MyCategory)
- (BOOL) startsWith: (NSString*) prefix;
@end

@protocol MyExtendedProtocolName <NSString>
//Method declarations go here
@end

이렇게하면 카테고리 헤더를 가져 오는 클래스도 프로토콜 정의도 얻을 수 있으며 클래스에 추가 할 수 있습니다.

@interface MyClass <OriginalProtocol,MyExtendedProtocolName>

또한 NSSTRING을 서브 클래스 할 때 조심하십시오. 클러스터이며 항상 기대하는 동작을 얻을 수는 없습니다.

아담 샤프 솔루션을 게시했습니다 그것은 나를 위해 일했다.

3 단계가 포함됩니다.

  1. AS를 추가하려는 메소드를 정의합니다 @optional 프로토콜에.
  2. 확장하려는 객체를 해당 프로토콜을 준수합니다.
  3. 런타임에 해당 메소드를 해당 객체에 복사합니다.

자세한 내용은 링크를 확인하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top