Objective-C에서 범주를 사용하여 메서드 재정의


87

범주를 사용하여 이미 구현 된 메서드를 재정의하기 위해 클래스 범주를 사용할 수 있습니까? 이렇게 :

1) 원래 방법

-(BOOL) method {
  return true;
}

2) 재정의 된 방법

-(BOOL) method {
  NSLog(@"error?"); 
  return true; 
}

이것이 효과가 있습니까, 아니면 불법입니까?

답변:


146

에서 애플 문서 :

Objective-C 언어는 현재 카테고리를 사용하여 클래스가 상속하는 메서드 또는 클래스 인터페이스에서 선언 된 메서드 를 재정의 할 수 있지만 그렇게하지 않는 것이 좋습니다 . 범주는 하위 클래스를 대체하지 않습니다. 범주를 사용하여 메서드를 재정의하는 데는 몇 가지 중요한 단점이 있습니다.

  • 카테고리가 상속 된 메소드를 재정의하면 카테고리의 메소드는 평소와 같이에 대한 메시지를 통해 상속 된 구현을 호출 할 수 있습니다 super. 그러나 카테고리가 카테고리의 클래스에있는 메소드를 재정의하는 경우 원래 구현을 호출 할 방법이 없습니다 .

  • 범주는 동일한 클래스의 다른 범주에서 선언 된 메서드를 안정적으로 재정의 할 수 없습니다.

    이 문제는 많은 Cocoa 클래스가 카테고리를 사용하여 구현되기 때문에 특히 중요합니다. 재정의하려는 프레임 워크 정의 메서드 자체가 범주에 구현되었을 수 있으므로 어떤 구현이 우선 적용되는지 정의되지 않았습니다.

  • 일부 범주 메서드의 존재만으로도 모든 프레임 워크에서 동작이 변경 될 수 있습니다. 예를 들어 windowWillClose:NSObject의 범주에서 delegate 메서드 를 재정의하면 프로그램의 모든 창 대리자가 범주 메서드를 사용하여 응답합니다. NSWindow의 모든 인스턴스의 동작이 변경 될 수 있습니다. 프레임 워크 클래스에 추가하는 카테고리는 동작에 신비한 변화를 일으키고 충돌을 일으킬 수 있습니다.


고맙지 만 이미 알고 있습니다. 제 사건이 합법적인지 아닌지 궁금합니다. 제 경우는 문서와 약간 다릅니다. :)
retix 2011 년

왜 다른가요? 문서는 원래 방법이 범주에 속하지 않는 경우 합법적이라고 말하지만 강력히 권장하지 않습니다. 그러면 할 수 있습니다 ...
Benoît

1
조언 감사합니다. 나는이 언어가 가난합니다. 나는 당신에게서 새로운 정보를 얻었습니다.
retix 2011 년

1
수퍼 클래스의 Category에서 선언하고 구현 한 Category 메서드에서 재정의하는 것이 맞습니까?
BergP 2013 년

2
링크가 끊어졌습니다. 새 버전입니까? developer.apple.com/library/ios/documentation/Cocoa/Conceptual/...
RndmTsk


9

이전 문서 링크가 작동하지 않습니다. 내가 찾을 수있는 최고의 대체품은 여기였다 : Apple Docs :

카테고리 메소드 이름 충돌 방지

카테고리에 선언 된 메소드는 기존 클래스에 추가되기 때문에 메소드 이름에 매우주의해야합니다.

범주에 선언 된 메서드의 이름이 원래 클래스의 메서드와 같거나 동일한 클래스 (또는 수퍼 클래스)의 다른 범주에있는 메서드와 동일하면 어떤 메서드 구현이 사용되는지에 대한 동작이 정의되지 않습니다. 실행 시간. 자체 클래스에 범주를 사용하는 경우 문제가 될 가능성이 적지 만 범주를 사용하여 표준 Cocoa 또는 Cocoa Touch 클래스에 메서드를 추가 할 때 문제가 발생할 수 있습니다.

더 가벼운 터치를 사용하는 것은 Apple이지만 요점은 동일합니다. 예측할 수없는 행동이 조용하기 때문에 재난을 초래합니다.


2

카테고리를 사용하여 기본 클래스의 기존 메서드 (예 : Car 클래스의 드라이브 메서드)를 재정의 할 수도 있지만 이렇게하면 안됩니다. 문제는 카테고리가 평평한 조직 구조라는 것입니다. Car + Maintenance.m의 기존 메서드를 재정의 한 다음 다른 범주로 동작을 다시 변경하려는 경우 Objective-C가 사용할 구현을 알 수있는 방법이 없습니다. 이러한 상황에서는 서브 클래 싱이 거의 항상 더 나은 옵션입니다.

이 자습서에서 http://rypress.com/tutorials/objective-c/categories

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.