[Effective Objective-C] #28 프로토콜을 이용해 익명 객체를 제공하라.
출처 : Effective Objective-C
-
프로토콜은 프로토콜을 따르는 객체가 구현할(또는 선택(optional)이 아니라면 반드시 구현해야 할) 메서드들을 정의한다.
프로토콜은 API 의 자세한 구현 내용을 숨기기 위해 사용할 수 있는데, 그 방법은 반환하는 객체를 프로토콜을 따르는 평범한 id 타입으로 반환하는 것이다.
이 방법을 쓰면 특정 클래스 이름이 API 에 노출되지 않는다.
이는 인터페이스 뒤편에 수많은 종류의 클래스가 있고 그 모든 클래스를 명시하고 싶지 않을 때 유용하다.
다른 말로 하면 하나의 공통 기초 클래스(common base class) 타입으로 반환해야 하는 API 에서 반환해야 할 클래스 타입이 여러 가지이고 이 클래스들을 표준 클래스 계층 구조로 묶을 수 없을 때 사용될 수 있다.
-
이 개념은 익명 객체(anonymous object)로도 알려져 있다.
하지만 다른 언어의 익명 객체와는 개념이 다르다.
다른 언어의 익명 객체는 이름 없이 인라인으로 클래스를 생성할 수 있는 능력을 말한다.
오브젝티브-C 에서는 그렇지 않다.
-
익명 객체를 사용하는 예는 다음과 같다.
예를 들어 델리게이트를 위한 프로퍼티 정의는 다음과 같다.
@property (nonatomic, weak) id <EOCDelegate> delegate;
타입이 id <EOCDelegate> 이기 때문에 객체의 클래스는 어떠한 타입이라도 될 수 있다.
또 NSObject 로 상속받지 않은 클래스조차도 가능하다.
EOCDelegate 만 따르면 어떠한 것이든 괜찮다.
이 프로퍼티를 가진 클래스에서 Delegate 는 익명이다.
맘만 먹으면 실행 시간에 델리게이트의 클래스 타입을 알아낼 수도 있지만 좋지 않은 사용 예다.
프로퍼티 타입이 어떤 클래스라도 올 수 있다고 나타내고 있기 때문이다.
-
NSDictionary 는 이 개념을 적용한 또 다른 예다.
사전의 키에 대한 기본 메모리 관리 시맨틱은 값이 리테인될 때 키가 복사되는 것이다.
그렇기 때문에 가변사전(mutable dictionary)에서 키-값 쌍을 설정하는 메서드 시그너처는 다음과 같다.
-(void)setObject:(id)object forkey:(id<NSCopying>)key
키 파라미터는 id<NSCopying> 타입이다.
키는 copy 메시지를 보낼 수 있는 NSCopying 을 따르는 객체 타입이기만 하면 되기 때문이다.
-
라이브러리에서 반환하는 객체를 익명 객체로 사용하는 예는 데이터베이스 연결을 다루는 라이브러리에서 볼 수 있다.
백엔드 코드는 각각의 서로 다른 데이터베이스에 연결하는 여러 종류의 서드 파티 라이브러리일 수 있다.
그렇기 때문에 모든 연결 클래스가 같은 기본 클래스로부터 상속받게 하는 것은 불가능하다.
그 클래스들은 서드 파티 라이브러리이기 때문이다.
그래서 익명 객체는 EOCDatabaseConnection 프로토콜을 따르게 만들기 위해 이러한 서드 파티 클래스들의 하위 클래스로 생성되는 간단한 래퍼가 필요한 곳에 사용될 수 있다.
그러면 이 래퍼 클래스는 connectionWithIdentifier: 메서드에 의해 반환될 수 있다.
-
이러한 익명 타입은 전달할 객체의 타입이 중요하지 않고 특정 메서드를 구현했는지 여부가 더 중요할 때 유용하게 쓰인다.
기억할 점
프로토콜은 객체의 타입을 익명으로 만들기 위해 사용될 수 있다.
프로토콜 메서드를 구현하는 타입은 id 타입으로 줄일 수 있다.
타입(클래스 이름)을 숨겨야 할 때는 익명 객체를 사용하라.
어느 클래스 타입이든 별로 상관없고 특정(또는 프로토콜에 정의되어 있는) 메서드에 응답하는 사실이 더 중요할 때 익명 객체를 사용하라.
'프로그래밍 놀이터 > iOS' 카테고리의 다른 글
[iOS] Swift 는 어떻게 Objective-C 보다 훨씬 빠른가? (0) | 2017.09.14 |
---|---|
[iOS] Swift vs. Objective-C (0) | 2017.09.13 |
[Effective Objective-C] #27 클래스 확장 카테고리를 이용해 상세한 구현을 숨기라. (0) | 2017.09.11 |
[Effective Objective-C] #26 카테고리에는 프로퍼티를 사용하지 말라. (0) | 2017.09.10 |
[Effective Objective-C] #25 서드 파티 클래스에는 반드시 카테고리 이름을 접두어로 붙여라 (0) | 2017.09.09 |
댓글