How to build NSArray (or NSMutableArray) class methods in Objective-C?

I am trying to create NSArray methods in Objective-C .

(What I'm trying to do here in C) is as follows:

typedef (void)(*handler)(int command); void handleCommandA(void) { ... } void handleCommandB(void) { ... } static const handler handler_table[10] = { handleCommandA, handleCommandB, handleCommandC }; 

I need to port this to Objective-C, and I don’t know how to build an array of function pointers (in the world of Objective-C class methods) at compile time.

In Objective-C, I have the following.

 - (void)handleCommandA { ... } - (void)handleCommandB { ... } /* Now how to add above 2 functions into NSArray? */ NSArray *handler_table = [NSArray arrayWithObjects:... ]; /* This doesn't seem to work. */ 
+13
objective-c
Feb 22 '09 at 15:21
source share
3 answers

Use NSValue.

For example:

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

then for access:

 handleptr* handle = (handlerptr*)[[handlers objectAtIndex:0] pointerValue]; handle(foo_bar); 
+5
Apr 30 '09 at 15:54
source share

The problem is that you must use the selector keyword, which returns a SEL, to bind these functions. This is a pointer type, while NSArray stores objects.

Thus, you have three options:

  • Use a regular C-type array
  • Add the functions to the derived class NSObject, which will call them.
  • Use protocol.

The second is probably better, and for this you can use the NSValue class to store selector results. For example;

 NSValue* selCommandA = [NSValue valueWithPointer:@selector(handleCommandA:)]; NSValue* selCommandB = [NSValue valueWithPointer:@selector(handleCommandB:)]; NSArray *handler_table = [NSArray arrayWithObjects:selCommandA, selCommandB, nil ]; 

When you got the correct entry from the array to convert back, you would do:

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

(Note. I assume that from your objective-c syntax, they are intended to be used as methods for an object, not global functions. If you want to use them globally, you should write them like you would C.)

Another option is to formalize the command methods into the protocol. This allows you to write functionality that will work on any object that implements this protocol, and the compiler will provide more verification than if you simply called selectors.

eg.

 // 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 } 

Then the processing and sending code is processed to work with objects of the "CommandHandler" type. for example

 -(void) registerForCommands:(CommandHandler*)handler 
+28
Feb 22 '09 at 17:53
source share

In Objective-C, you do not bypass methods; you go through selectors, which are basically canonical method names. Then, for the object to respond to the selector message, you send it to performSelector: For example:

 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!"]; 

You want to create an NSStrings array containing the names of the selectors you are interested in. You can use the NSStringFromSelector() function for this. Then, when you want to use them, call NSSelectorFromString() on the lines to return the original selector and pass it to the corresponding performSelector: object. (As shown in the example above, the receiver is not encoded in the selector β€” just the name of the method β€” so you might need to save the receiver as well.)

+3
Feb 22 '09 at 18:35
source share



All Articles