목표 C 블록에서 임프를 생성합니다
문제
그만큼 IMP
Objective-C를 입력하면 이해하는 한 함수 포인터를 나타냅니다. 만들 수있는 방법이 있습니까? IMP
블록 포인터에서? 당신의 아이디어에 감사드립니다.
해결책
이것이 작성되었으므로 이제 iOS 및 Mac OS X에는 블록을 직접 IMPS로 전환 할 수있는 API가 있습니다. 나는 썼다 웹 로그 게시물 API 설명 (imp_implementationwithBlock ()).
블록은 효과적으로 약간의 메타 데이터를 포함하는 구조, 블록 내에 포함 된 코드에 대한 참조 및 블록 내에서 캡처 된 Const-COPIED 데이터의 사본입니다.
따라서, 아니, IMP
그리고 블록 참조.
블록으로의 호출이 컴파일되면 컴파일러는 스택 프레임을 설정하는 트램폴린을 방출 한 다음 블록 내에서 실행 가능한 코드로 이동합니다.
그러나 당신이 할 수있는 일은 그 트램폴린처럼 행동하는 임프를 창조하는 것입니다. 다음에는 각 인수 세트에 대해 하나의 특정 IMP가 필요합니다. 이 일반적인 것을 만들어야하는 경우 어셈블리를 사용해야합니다.
이를 위해 클래스 인스턴스 당 고유 한 블록 인스턴스를 설정합니다. 모든 인스턴스에서 작용하는 일반적인 블록을 원한다면 해시를 구축하십시오. SEL
-> 클래스 당 블록.
(1) 관련 참조 메커니즘을 사용하여 IMP로 작용하는 블록을 연관시킵니다. 같은 것 :
void (^implementingBlock)(id s, SEL _c, int v) = ^(id s, SEL _c, int v) {
// do something here
}
objc_setAssociatedObject(obj, SELToImp, [implementingBlock copy]));
(2) 트램폴린 임프를 이와 같은 것과 구현하십시오.
void void_id_sel_intTramp(id self, SEL _cmd, int value) {
int (^block)(id s, SEL _c, int v) = objc_getAssociatedObject(self, _cmd);
block(self, _cmd, value);
}
(3) Objective-C 런타임의 API를 통해 모든 선택기에 대해 위의 트램폴린을 넣습니다 ( method_setImplementation
그리고 좋아)
경고 :
이것은 stackoverflow로 입력되었습니다. 실제 코드는 비슷하지만 약간 다를 수 있습니다.
구현 블록 사본]은 중요합니다. 블록은 스택에서 수명을 시작합니다 (보통)