2012-07-31 2 views
2

두 개의 objective-c 클래스, LBFooLBBar이 있다고 가정합니다. 내가 대신 할 싶은 무엇사용자 지정 선택기 구현을 전달

- (void)doSomethingWithFoo:(NSNumber*)anArgument 
{ 
    if(anArgument.intValue > 2) 
    [LBBar doSomethingWithLBBar]; 
    else 
    [LBBar doSomethingElseWithLBBar]; 
} 

는 미리 선언하지 않은 LBBar에 구현을 전달할 수 있습니다 : LBFoo에서

나는이처럼 보이는 방법이있다.

나는 그것의 선택의 구현을 변경하기 위해 클래스에 IMP을 통과 할 수 있으며, IMP 타입이 존재한다는 것을 알고 (동적 마찬가지로 것은 LBBar 내에서 기존 @selector를 오버라이드 (override)).

답변

2

objective-c runtimemethod_setImplementation(Method method, IMP imp) 기능을 사용할 수 있습니다. 당신이 인스턴스 방법을 설정하려는 경우 클래스 메소드를 원하는 경우

, 그냥 class_getClassMethod 대신 class_getInstanceMethod를 사용,이

method_setImplementation(class_getInstanceMethod([yourClass class], @selector(yourMethod)), yourIMP); 

처럼 뭔가를 작동합니다. 인수는 동일해야합니다.

그게 전부입니다. IMP는 처음 2 개 매개 변수 id selfSEL _cmd되는 그냥 무효 함수 포인터 있습니다

+0

매우 유용합니다. 감사. –

1

당신은 확실히 *,이 같은 작업을 수행 할 런타임 기능을 사용할 수 있습니다하지만이 정확히의 종류는 것을 건의 할 것 해결하기 위해 Blocks이 소개 된 문제. 그것들은 실행 가능한 코드 덩어리를 전달할 수 있도록 해줍니다 - 당신의 메소드는 실제로 블록을 인수로 받아 들여 실행할 수 있습니다.

는 여기 SSCCE입니다 :

#import <Foundation/Foundation.h> 

typedef dispatch_block_t GenericBlock; 

@interface Albatross : NSObject 
- (void)slapFace:(NSNumber *)n usingFish:(GenericBlock)block; 
@end 

@implementation Albatross 

- (void)slapFace:(NSNumber *)n usingFish:(GenericBlock)block 
{ 
    if([n intValue] > 2){ 
     NSLog(@"Cabbage crates coming over the briny!"); 
    } 
    else { 
     block(); // Execute the block 
    } 
} 

@end 

int main(int argc, const char * argv[]) 
{ 

    @autoreleasepool { 

     Albatross * p = [Albatross new]; 
     [p slapFace:[NSNumber numberWithInt:3] usingFish:^{ 
      NSLog(@"We'd like to see the dog kennels, please."); 
     }]; 
     [p slapFace:[NSNumber numberWithInt:1] usingFish:^{ 
      NSLog(@"Lemon curry?"); 
     }]; 

    } 
    return 0; 
} 

*이 방법은 어디에서 미래에 호출 될 때마다 사용되는 코드를 변경합니다 method_setImplementation()를 사용합니다 - 그것은 영구적 인 변화입니다.

+0

이 조쉬에게 감사드립니다. 저는 실제로 변경 사항이 영구적으로 유지되도록하려고합니다. 동적 메서드 생성을 통해 메타 프로그래밍을 약간 수행합니다. –

+3

[ "Messaging"] (http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtHowMessagingWorks.html%23//apple_ref/doc/uid/)을 참조하십시오. TP40008048-CH104), "Dynamic Method Resolution"및 "Message Forwarding"장 (ObjC 런타임 프로그래밍 가이드)을 참조하십시오. 어쨌든'method_setImplementation()'을 사용하게 될지도 모르지만, NSObject에 내장 된 동적 메시지 처리에 대한 좀 더 높은 수준의 지원이 있습니다. –