문제

Objective C에서 카테고리와 상속의 차이점을 설명해 줄 수 있는 사람이 있나요?나는 읽었다 Wikipedia의 항목 그리고 범주에 대한 논의는 상속에 대한 논의와 전혀 다르지 않습니다.또한 "Open iPhone Development"라는 책에서 해당 주제에 대한 토론을 보았는데 여전히 이해가 되지 않습니다.

도움이 되었습니까?

해결책

때로는 상속이 가치있는 것보다 더 많은 문제처럼 보입니다. 해당 클래스의 동작의 변화 인 기존 클래스에 무언가를 추가하려는 경우 올바르게 사용됩니다.

카테고리를 사용하면 기존 객체가 조금 더 수행되기를 원합니다. 이미 주어진 바와 같이, 압축을 처리하는 문자열 클래스를 원한다면 문자열 클래스를 서브 클래스 할 필요가 없으므로 압축을 처리하는 범주 만 만듭니다. 그렇게하면 이미 사용하고있는 문자열 클래스의 유형을 변경할 필요가 없습니다.

단서는 범주 만 메소드를 추가하는 제한에 있으며, 범주를 사용하여 클래스에 변수를 추가 할 수 없습니다. 클래스에 더 많은 속성이 필요한 경우 서브 클래스가 필요합니다. (편집 : 연관성 저장소를 사용할 수 있습니다.

카테고리는 기능을 추가하는 좋은 방법이며 동시에 상속을 통해 구성을 선호하기 위해 객체 지향 원칙을 준수하는 동시에 좋은 방법입니다.

2012 년 1 월 편집

이제 상황이 바뀌 었습니다. 현재 LLVM 컴파일러와 최신 64 비트 런타임을 사용하면 클래스에 IVARS 및 속성을 추가 할 수 있습니다. 확장 (카테고리 아님). 이를 통해 개인 IVARS를 공개 인터페이스에서 멀리 떨어 뜨릴 수 있습니다. 그러나 IVAR에 대한 속성을 선언하는 경우 KVC를 통해 여전히 액세스 / 변경 될 수 있습니다. 대물 픽에 개인 방법이 여전히 없기 때문입니다.

다른 팁

카테고리를 사용하면 기존 클래스에 메소드를 추가 할 수 있습니다. 따라서 NSData 서브 클래스 NSData 대신 펑키 한 새로운 암호화 방법을 추가하여 NSDATA 클래스에 직접 추가 할 수 있습니다. 앱의 모든 NSDATA 객체는 이제 이러한 방법에 액세스 할 수 있습니다.

이것이 얼마나 유용한 지 확인하려면 다음을보십시오. Cocoadev

Objective-c 카테고리의 작동 중 가장 좋아하는 그림 중 하나는 NSString입니다.NSString은 뷰나 창에 대한 개념이 없는 Foundation 프레임워크에 정의되어 있습니다.그러나 Cocoa 애플리케이션에서 NSString을 사용하면 다음과 같은 메시지에 응답하는 것을 볼 수 있습니다. – drawInRect:withAttributes:.

AppKit은 추가 그리기 방법을 제공하는 NSString 카테고리를 정의합니다.카테고리를 사용하면 기존 클래스에 새 메소드를 추가할 수 있으므로 여전히 NSString만 다루고 있습니다.대신 AppKit이 서브클래싱을 통해 그리기를 구현했다면 'AppKitStrings' 또는 'NSSDrawableStrings' 또는 이와 유사한 것을 처리해야 합니다.

카테고리를 사용하면 기존 클래스에 애플리케이션 또는 도메인별 메서드를 추가할 수 있습니다.매우 강력하고 편리할 수 있습니다.

프로그래머로서 코드 라이브러리 또는 응용 프로그램에 대한 전체 소스 코드 세트가 제공되는 경우 해당 코드로 프로그래밍 목표를 달성하는 데 필요한 모든 것을 변경하고 변경할 수 있습니다.

불행히도, 이것은 항상 사건이나 바람직한 것은 아닙니다. 여러 번 바이너리 라이브러리/객체 키트와 함께 할 헤더 세트가 제공됩니다.

그런 다음 수업에는 새로운 기능이 필요하므로 몇 가지 작업을 수행 할 수 있습니다.

  1. 재고 클래스 대신 새 클래스 전체를 만듭니다. 모든 기능과 멤버를 복제 한 다음 모든 코드를 다시 작성하여 새 클래스를 사용하십시오.

  2. 재고 클래스를 멤버로 포함하는 새 래퍼 클래스를 작성하고 (합성) 코드베이스를 다시 작성하여 새 클래스를 활용하십시오.

  3. 코드를 변경하기 위해 라이브러리의 이진 패치 (행운)

  4. 컴파일러가 새로운 클래스를 이전 클래스로 보도록 강요하고 메모리 및 특정 입력 지점의 특정 크기 나 장소에 의존하지 않기를 바랍니다.

  5. 서브 클래스 전문화 - 서브 클래스를 작성하여 기능을 추가하고 드라이버 코드를 수정하여 서브 클래스를 대신 사용합니다. 이론적으로 문제가 거의 없어야하며 데이터 구성원을 추가 해야하는 경우 필요한 경우 메모리 풋 프린트가 다릅니다. 새 코드와 이전 코드를 서브 클래스로 사용할 수 있고 사용할 것, 기본 클래스 방법 또는 재정의 메소드를 선택할 수 있다는 이점이 있습니다.

  6. 원하는 작업을 포함하는 카테고리 정의로 필요한 OBJC 클래스를 수정하여 원하는 작업을 수행하고 재고 클래스에서 이전 방법을 재정의합니다.

    또한 라이브러리의 오류를 수정하거나 새로운 하드웨어 장치 또는 무엇이든에 대한 메소드를 사용자 정의 할 수 있습니다. 만병 통치약은 아니지만 변경되지 않은 클래스/라이브러리를 다시 컴파일하지 않고 클래스 방법을 추가 할 수 있습니다. 원래 클래스는 코드, 메모리 크기 및 진입 지점에서 동일하므로 레거시 앱이 깨지지 않습니다. 컴파일러는 단순히 새로운 메소드를 해당 클래스에 속하는 런타임에 넣고 원래 코드와 동일한 서명으로 메소드를 무시합니다.

    an example:

    당신은 터미널에 출력하는 클래스 빙이 있지만 직렬 포트에 대한 것이 아니라 이제는 필요한 것입니다. (몇 가지 이유). 당신은 bing.h와 libbing.so가 있지만 키트에는 bing.m이 없습니다.

    Bing 클래스는 내부적으로 모든 종류의 물건을 수행합니다. 모든 것을 알지 못합니다. 헤더에 공개 API가 있습니다.

    당신은 똑똑하기 때문에 Bing 클래스에 대한 (SerialOutput) 카테고리를 만듭니다.

    [Bing_SerialOutput.m]
    @interface Bing (SerialOutput)   // a category
    - (void)ToSerial: (SerialPort*) port ;
    @end
    
    @implementation Bing (SerialOutput)
    - (void)ToSerial: (SerialPort*) port 
    {
    ... /// serial output code ///
    }
    @end
    

    컴파일러는 앱과 연결될 수있는 객체를 만들어야하며 런타임은 이제 Bing이 @Selector (toserial :)에 응답한다는 것을 알고 있으며 Bing 클래스가 해당 방법으로 구축 된 것처럼 사용할 수 있습니다. 데이터 멤버 전용 방법을 추가 할 수 없으며 이는 기본 클래스에 첨부 된 거대한 코드 종양을 만들기위한 것이 아니라 엄격하게 입력 한 언어에 비해 장점이 있습니다.

이러한 답변 중 일부는 상속이 기존 클래스에 기능을 추가하는 데 더 무거운 방법이지만 카테고리는 더 가볍다는 생각을 적어도 지적한다고 생각합니다.

상속은 새로운 클래스 계층 구조 (모든 종과 휘파람)를 만들 때 사용되며 기존 클래스에 기능을 추가하는 방법으로 선택할 때 많은 작업을 제공합니다.

여기에 다른 사람이 말한대로 ... 상속을 사용하여 NSString에 새 방법을 추가하는 경우이 새 방법을 사용하려는 다른 코드에서 사용중인 유형을 변경해야합니다. 그러나 카테고리를 사용하는 경우 서브 클래싱없이 기존 NSString 유형의 메소드를 호출 할 수 있습니다.

어느 쪽이든 동일한 끝을 달성 할 수 있지만 카테고리는 더 간단하고 유지 보수가 적은 옵션을 제공하는 것 같습니다 (아마도).

범주가 절대적으로 필요한 상황이 있는지 아는 사람이 있습니까?

카테고리는 믹스 인과 같습니다. 루비의 모듈이거나 Java의 인터페이스와 다소 비슷합니다. 당신은 그것을 "벌거 벗은 방법"으로 생각할 수 있습니다. 카테고리를 추가하면 클래스에 메소드를 추가합니다. Wikipedia 기사가 있습니다 좋은 것들.

이 차이점을 보는 가장 좋은 방법은 다음과 같습니다. 1. 상속 : 정확히 당신의 방식으로 바꾸고 싶을 때. 예 : AsyncimageView 게으른 하중을 구현하려면. Uiview를 상속하여 수행됩니다. 2. 카테고리 : 그냥 추가 맛을 추가하고 싶습니다. 예 : 텍스트 필드 텍스트에서 모든 공간을 교체하고 싶습니다.

   @interface UITextField(setText)
      - (NSString *)replaceEscape;
   @end

   @implementation UITextField(setText)
      - (NSString *)replaceEscape
      {
         self.text=[self.text stringByTrimmingCharactersInSet:
                           [NSCharacterSet whitespaceCharacterSet]];
         return self.text;
      }
   @end

--- 모든 흰색 공간을 탈출 할 수 있도록 텍스트 필드에 새로운 속성을 추가합니다. 완전히 바뀌지 않고 새로운 차원을 추가하는 것과 같습니다.

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