범주를 사용하여 이미 구현 된 메서드를 재정의하기 위해 클래스 범주를 사용할 수 있습니까? 이렇게 :
1) 원래 방법
-(BOOL) method {
return true;
}
2) 재정의 된 방법
-(BOOL) method {
NSLog(@"error?");
return true;
}
이것이 효과가 있습니까, 아니면 불법입니까?
답변:
에서 애플 문서 :
Objective-C 언어는 현재 카테고리를 사용하여 클래스가 상속하는 메서드 또는 클래스 인터페이스에서 선언 된 메서드 를 재정의 할 수 있지만 그렇게하지 않는 것이 좋습니다 . 범주는 하위 클래스를 대체하지 않습니다. 범주를 사용하여 메서드를 재정의하는 데는 몇 가지 중요한 단점이 있습니다.
카테고리가 상속 된 메소드를 재정의하면 카테고리의 메소드는 평소와 같이에 대한 메시지를 통해 상속 된 구현을 호출 할 수 있습니다
super
. 그러나 카테고리가 카테고리의 클래스에있는 메소드를 재정의하는 경우 원래 구현을 호출 할 방법이 없습니다 .범주는 동일한 클래스의 다른 범주에서 선언 된 메서드를 안정적으로 재정의 할 수 없습니다.
이 문제는 많은 Cocoa 클래스가 카테고리를 사용하여 구현되기 때문에 특히 중요합니다. 재정의하려는 프레임 워크 정의 메서드 자체가 범주에 구현되었을 수 있으므로 어떤 구현이 우선 적용되는지 정의되지 않았습니다.
일부 범주 메서드의 존재만으로도 모든 프레임 워크에서 동작이 변경 될 수 있습니다. 예를 들어
windowWillClose:
NSObject의 범주에서 delegate 메서드 를 재정의하면 프로그램의 모든 창 대리자가 범주 메서드를 사용하여 응답합니다. NSWindow의 모든 인스턴스의 동작이 변경 될 수 있습니다. 프레임 워크 클래스에 추가하는 카테고리는 동작에 신비한 변화를 일으키고 충돌을 일으킬 수 있습니다.
클래스 클러스터 접근 방식 을 적용 하거나 방법 전환 기법을 사용하여 이를 수행 할 수 있습니다 .
그렇지 않으면 둘 이상의 분류 된 메서드 의 동작 이 정의되지 않습니다.
이전 문서 링크가 작동하지 않습니다. 내가 찾을 수있는 최고의 대체품은 여기였다 : Apple Docs :
카테고리 메소드 이름 충돌 방지
카테고리에 선언 된 메소드는 기존 클래스에 추가되기 때문에 메소드 이름에 매우주의해야합니다.
범주에 선언 된 메서드의 이름이 원래 클래스의 메서드와 같거나 동일한 클래스 (또는 수퍼 클래스)의 다른 범주에있는 메서드와 동일하면 어떤 메서드 구현이 사용되는지에 대한 동작이 정의되지 않습니다. 실행 시간. 자체 클래스에 범주를 사용하는 경우 문제가 될 가능성이 적지 만 범주를 사용하여 표준 Cocoa 또는 Cocoa Touch 클래스에 메서드를 추가 할 때 문제가 발생할 수 있습니다.
더 가벼운 터치를 사용하는 것은 Apple이지만 요점은 동일합니다. 예측할 수없는 행동이 조용하기 때문에 재난을 초래합니다.
카테고리를 사용하여 기본 클래스의 기존 메서드 (예 : Car 클래스의 드라이브 메서드)를 재정의 할 수도 있지만 이렇게하면 안됩니다. 문제는 카테고리가 평평한 조직 구조라는 것입니다. Car + Maintenance.m의 기존 메서드를 재정의 한 다음 다른 범주로 동작을 다시 변경하려는 경우 Objective-C가 사용할 구현을 알 수있는 방법이 없습니다. 이러한 상황에서는 서브 클래 싱이 거의 항상 더 나은 옵션입니다.