메소드의 포인터


메소드를 함수로 호출

실은, Objective-C의 메소드의 실태는 C 언어의 함수와 동일합니다. 평상시는 은폐되고 있습니다 만, 메소드는 첫 번째 인수에 자신의 클래스를 참조하는 개체를받는 함수입니다.

메소드의 실체가 함수라는 사실은 C 언어와의 친 화성이 매우 높다는 것을 의미합니다. 순수한 C로 작성된 라이브러리에서 Objective-C의 메소드를 호출하거나 객체를 이용하는 것도 무리한 이야기는 아닙니다.

Objective-C의 메소드는 항상 IMP 형으로 정의됩니다. IMP 형은 헤더 파일에서 다음과 같이 정의되어 있습니다.

typedef id (* IMP) (id, SEL, ...);

이 정의에서 알 수 있듯이, Objective-C에서 선언 된 모든 메소드는 암시 적으로 id 형과 SEL 형의 인수를가집니다. 첫 번째 인수는 메소드를 호출 한 객체를 나타내는 변수 self입니다. 두 번째 인수는이 메소드의 셀렉터를 나타내는 변수 _cmd 입니다. 모든 메소드는 이러한 숨겨진 인수가 반드시 존재합니다. 그런 다음 메소드의 선언에 따라 인수가 결정되는 것입니다.

C 언어 나 어떤 이유로 Objectiver-C에서 메소드를 함수로 호출 할 필요가있는 경우, 메소드를 참조하는 함수에 대한 포인터를 취득하면 좋은입니다. 메소드를 참조하는 IMG 형의 포인터는 Object 클래스의 instanceMethodFor 클래스 메소드 또는 methodFor 인스턴스 메소드에서 얻을 수 있습니다.

+ (IMP) instanceMethodFor : (SEL) aSel;

- (IMP) methodFor : (SEL) aSel;

aSel는 대상 메소드의 IMP, 즉 함수에 대한 포인터를 취득하고 싶은 실렉터를 지정합니다. 메소드는 aSel에 지정된 셀렉터가 특정하는 메소드의 포인터를 돌려줍니다.

포인터를 얻을 수 있다면 C 언어에서도 인스턴스 메소드를 호출 할 수 있습니다. 함수 포인터로 직접 전화, 메시지 전달보다 빠를 수 있다는 점도 특징 이지요.

#import <stdio.h>
#import <objc / Object.h>

@interface Test : Object
- (void) Write;
@end

@implementation Test
- (void) Write {
	printf ( "I am the bone of my sword \ n");
}
@end

int main () {
	id obj;
	SEL method;
	IMP func;

	obj = [Test new];
	method = @selector (Write);
	func = [Test instanceMethodFor : method];
	func (obj, method);

	return 0;
}

이 프로그램은 Test 클래스의 인스턴스 메소드 Write 포인터를 취득 해, IMP 형의 변수 func에 저장합니다. [Test instanceMethodFor : method]라는 메시지 식의 부분은 [obj methodFor : method]로도 의미는 동일합니다. 이 메시지식이 돌려 준 IMP 형의 메소드의 포인터를 사용하여 직접 메소드를 호출합니다.

화상 처리 나 멀티미디어 등, 루프 처리의 고속화 등이 필요한 경우 메시지 통신 선택기 통신은 부담이 커집니다. 속도에 집착하는 프로그램이면, 필요에 따라 IMP를 가져 포인터에서 메소드를 호출해도 좋을 것입니다.