클래스 확장 대 클래스 범주


82

클래스 확장 @interface Class () 은 훨씬 더 강력하며 변수를 클래스에 삽입 할 수 있습니다. 카테고리 @interface Class (Category)는 할 수 없습니다.

다른 어떤 차이점이 있으며 언제 클래스 확장보다 카테고리를 사용해야합니까?


카테고리는 실제 코드입니다. 수업에 기능을 추가하는 방법입니다. 확장은 (매우 일반적인 용어로) 다른 프로그래머에게 프라이버시 등에 대한 특정 아이디어를 알리기 위해 구문 적 설탕에 가깝습니다. 확장자는 코드를 포함하지 않으며 코드가 아닙니다.
Fattie 2013-12-03

Swift에서 사용되는 확장에 대해서는 다음 질문을 참조하십시오. stackoverflow.com/questions/24142829/…
Suragch

답변:


91

가장 큰 차이점은 확장을 사용하면 컴파일러가 main 내에서 메서드를 구현할 것으로 예상 @implementation하는 반면 카테고리를 사용하면 별도의 @implementation블록이 있다는 것입니다. 당신이 거의 유일한 메인의 상단에 확장을 사용해야합니다 그래서 .m파일합니다 (은 당신이 부수적으로, 인스턴스 변수에 대해 관심을 가져야 배치) - 단지, 될 운명이야 확장 .


41
확장자는 .m파일 에서 선언하려는 개인 메서드에 가장 적합 합니다. 나는 이것을 위해 항상 그것을 사용합니다. 범주는 메서드를 다른 섹션 ( 범주 :) 으로 그룹화 하거나 만들지 않은 기존 클래스에 코드를 추가 하려는 경우에 더 유용합니다 .
jtbandes

1
속성을 사용하여 추가 스토리지를 추가 할 수도 있습니다.
Paul.s

23
클래스 확장은 또한 속성을 공개 readonly및 비공개 로 허용하도록 특별히 설계되었습니다 readwrite. 카테고리 (의식적인 디자인 선택)로는 그렇게 할 수 없습니다.
bbum

Google이 카테고리를 사용하여 확장 대신 비공개 메소드를 구현하는 이유는 무엇입니까? 예를 들어 code.google.com/p/gdata-objectivec-client/source/browse/trunk/...
라이언

확장은 모든 메소드가 @implementation 블록에 구현되어야하며 변수에 대한 향상도 제공합니다. 그러나 우리는 기본적으로 그렇게 그 경우 우리는 대신 확장의 카테고리 선호하는 대신 개인 변수를 사용하는 개인 방법의 일부를 넣어하려고
ANKIT 딴

29

클래스 확장은 범주와 약간 유사하지만 컴파일 타임에 소스 코드가있는 클래스에만 추가 할 수 있습니다 (클래스는 클래스 확장과 동시에 컴파일 됨). 클래스 확장에 의해 선언 된 메서드는 원래 클래스의 @implementation 블록에서 구현되므로 예를 들어 NSString과 같은 Cocoa 또는 Cocoa Touch 클래스와 같은 프레임 워크 클래스에서 클래스 확장을 선언 할 수 없습니다.

클래스 확장을 선언하는 구문은 범주 구문과 유사하며 다음과 같습니다.

@interface ClassName ()
@end

괄호 안에 이름이 지정되어 있지 않기 때문에 클래스 확장을 종종 익명 범주라고합니다.

일반 범주와 달리 클래스 확장은 자체 속성과 인스턴스 변수를 클래스에 추가 할 수 있습니다. 다음과 같이 클래스 확장에서 속성을 선언하는 경우 :

@interface XYZAnimal () {
    id _someCustomInstanceVariable;
}
...
@end

IMHO, 클래스 확장을 클래스에 대한 개인 인터페이스로 생각하는 것이 가장 좋습니다. .h 파일에있는 기본 인터페이스는 다른 클래스와 클래스의 동작 계약을 정의하는 공용 인터페이스 역할을합니다.

클래스 확장을 사용하여 개인 정보 숨기기

클래스 확장은 종종 클래스 자체 구현 내에서 사용하기 위해 추가 개인 메서드 또는 속성으로 공용 인터페이스를 확장하는 데 사용됩니다. 예를 들어, 인터페이스에서 읽기 전용으로 속성을 정의하는 것이 일반적이지만 클래스의 내부 메서드가 속성 값을 직접 변경할 수 있도록 구현 위에 선언 된 클래스 확장에서 읽기 쓰기로 정의합니다.

예를 들어 XYZPerson 클래스는 미국의 사회 보장 번호와 같은 정보를 추적하도록 설계된 uniqueIdentifier라는 속성을 추가 할 수 있습니다.

일반적으로 실제 개인에게 고유 한 식별자를 할당하려면 많은 양의 서류 작업이 필요하므로 XYZPerson 클래스 인터페이스는이 속성을 읽기 전용으로 선언하고 다음과 같이 식별자 할당을 요청하는 몇 가지 메서드를 제공 할 수 있습니다.

@interface XYZPerson : NSObject
    ...
    @property (readonly) NSString *uniqueIdentifier;
    - (void)assignUniqueIdentifier;
@end

XYZPerson 클래스가 속성을 내부적으로 변경할 수 있으려면 클래스의 구현 파일 맨 위에 정의 된 클래스 확장에서 속성을 다시 선언하는 것이 좋습니다.

@property (readwrite) NSString *uniqueIdentifier;

참고 : readwrite 속성은 기본값이므로 선택 사항입니다. 명확성을 위해 속성을 재 선언 할 때 사용할 수 있습니다.


7

범주는 기존 클래스에 새 메서드를 추가 할 수있는 Objective-C 언어 기능입니다. 확장은 기본 구현 블록에서 구현해야하는 메서드를 정의 할 수있는 특수한 범주의 경우입니다.

private 선언은 메서드를 호출하기 전에 선언 할 필요가 없기 때문에 주로 일부 속성 인 클래스 확장에있을 수 있습니다.


"메인 구현 블록에서 선언해야합니다." -> 그 주요 구현 블록에 "실행"해야
폭스

감사합니다. 수정했습니다.
Julie Yu

0

c #, java 추상 클래스 또는 인터페이스와
유사한 ios 확장 c # 클래스 확장과 유사한 ios 범주


Java는 확장 메소드를 지원하지 않습니다
someUser

죄송합니다 ! 오타를 복사하여 붙여 넣습니다. c # 클래스 확장과 유사한 ios 범주.
Add080bbA

에 대한 예를 추가 할 수 있습니까?
Pedro Trujillo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.