Objective-C에서 클래스 메서드의 NSArray (또는 NSMutableArray)를 작성하는 방법은 무엇입니까?


14

Objective-C에 메서드의 NSArray를 작성하려고합니다.

내가 목표 - C로 포트에이 있고 난의 배열을 구축 하는 방법을 모른다

합니다 (C에서 다음과 같은 뭔가 내가 여기 달성하기 위해 노력하고있다) 함수 포인터 (Objective-c 세계에서는 클래스 메쏘드)를 컴파일 할 때.

Objective-C에는 다음이 있습니다.

- (void)handleCommandA { ... } 
- (void)handleCommandB { ... } 

/* Now how to add above 2 functions into NSArray? */
NSArray *handler_table = [NSArray arrayWithObjects:... ]; /* This doesn't seem to work. */
5

NSValue를 사용합니다. 예를 들어

:

다음
NSArray* handlers = [NSArray arrayWithObjects:[NSValue valueWithPointer:handleA] ... ]; 

액세스 : 훨씬 더 쉽게 디버깅 할 것 같은

handleptr* handle = (handlerptr*)[[handlers objectAtIndex:0] pointerValue]; 
handle(foo_bar); 

28

여기서 문제는 이러한 함수를 바인딩하려면 SEL 유형을 반환하는 selector 키워드를 사용해야한다는 것입니다. 이것은 NSArray가 객체를 저장하는 반면 포인터 유형입니다.

이렇게 세 가지 옵션이 있습니다.

  1. 그들을 호출 할 것이다 NSObject의 파생 클래스에 기능을 접어 일반 C 형 배열
  2. 를 사용합니다.
  3. 프로토콜을 사용하십시오.

두 번째 가능성이 높습니다.이 때문에 NSValue 클래스를 사용하여 선택기 결과를 저장할 수 있습니다. 예 :

NSValue* selCommandA = [NSValue valueWithPointer:@selector(handleCommandA:)]; 
NSValue* selCommandB = [NSValue valueWithPointer:@selector(handleCommandB:)]; 

NSArray *handler_table = [NSArray arrayWithObjects:selCommandA, selCommandB, nil ]; 

배열에서 올바른 항목을 가져 왔으면 다시 변환 할 수 있습니다.

SEL mySelector = [selCommand pointerValue]; 
[someObject performSelector:mySelector]; 

(I이이 객체의 메소드가 아닌 글로벌 함수로 사용하기위한 것입니다 당신의 목표 - C 구문에서 해당 있으리라 믿고있어합니다. 당신은 당신이로 작성해야 세계적으로이를 사용하고자하는 경우 당신은 보통 C로 표현할 것입니다.)

또 다른 옵션은 명령 메소드를 프로토콜로 형식화하는 것입니다. 이렇게하면 해당 프로토콜을 구현하는 모든 객체에서 작동하는 기능을 작성할 수 있으며 컴파일러는 선택기를 호출하는 것보다 더 많은 검사를 제공합니다.

예.

//some header 
@protocol CommandHandler 
@required 
-(void) handleCommandA; 
-(void) handleCommandB; 
@end 

//some other header 
@interface someClass : NSObject<CommandHandler> 
{ 
//you will receive compiler warnings if you do not implement the protocol functions 
} 

처리 및 발송 코드는 "CommandHandler"유형의 개체와 함께 작동하도록 작성됩니다. 예 :

-(void) registerForCommands:(CommandHandler*)handler 
  0

내가 대신 포인터의 문자열을 사용하는 것을 선호 것입니다. NSStringFromSelector() 및 NSSelectorFromString()을 살펴보십시오. 17 may. 092009-05-17 09:10:39

+1

셀렉터를 사용하여 작은 수정 실제로 같습니다 : [someObject performSelector : mySelector]; 19 jan. 112011-01-19 03:30:33


4

Objective-C에서는 메소드를 전달하지 않습니다. 당신은 주위에 선택자, 기본적으로 방법의 정식 이름을 전달합니다. 그런 다음 선택기 메시지에 응답하도록 개체를 보내려면 performSelector:을 보냅니다. 예를 들면 : 당신이 원하는 것들

NSString *exampleString = [NSString stringWithString:@"Hello"]; 
SEL methodName = @selector(stringByAppendingString:); 
    //^This is the selector. Note that it just represents the name of a 
    //message, and doesn't specify any class or implementation 
NSString *combinedString = [exampleString performSelector:methodName withObject:@" world!"]; 

당신이 관심있는 선택기의 이름을 포함하는 NSStrings의 배열을 만드는 것입니다 당신은이 작업을 수행 할 기능 NSStringFromSelector()을 사용할 수 있습니다.. 그런 다음 문자열을 사용하려면 문자열의 NSSelectorFromString()으로 전화하여 원래의 선택기를 다시 가져 와서 해당 객체의 performSelector:에 전달합니다.위의 예에서와 같이 수신기는 선택기 (메서드 이름 만 인코딩 됨)에 인코딩되지 않으므로 수신기를 저장해야 할 수도 있습니다.