문제

그만큼 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로 입력되었습니다. 실제 코드는 비슷하지만 약간 다를 수 있습니다.

  • 구현 블록 사본]은 중요합니다. 블록은 스택에서 수명을 시작합니다 (보통)

다른 팁

나는 Landon Fuller의 도움을 받아 Mike Ash가 iOS를 포함한 일반적인 경우에 이것을 해결했다고 생각합니다. 그는 수업이 있습니다 github 블록을 함수 포인터로 바꿀 것입니다.

당신은 또한 회의를 원할 수도 있습니다 발표 그리고 코코아 노바운드에 대한 흥미로운 후속 토론.

업데이트 : 그리고 지금 있습니다 imp_implementationWithBlock() 위에서 언급 한 바와 같이.

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