Some of Apple's obj-c API's still use C functions, e.g.:
-(NSArray * ) sortedArrayUsingFunction: (NSInteger (*)(id, id, void *))comparator context:(void *)context
...which is great, except I'm struggling to see how you can store fn-pointers inside ObjC classes.
e.g. to share the same "sort" function in different parts of your program. Say you have different data, in different contexts/classes, but you want the same sort in both places (for consistency).
I'm sure this is simple, but either my C is too rusty, or there's some gotcha. I tried sticking a开发者_运维技巧 plain variable inside the header file:
NSInteger (*)(id, id, void *) myComparator;
...and all I get is a compiler error:
Expected identifier or '(' before ')' token
Instead of doing:
NSInteger (*)(id, id, void *) myComparator;
Use this instead:
NSInteger (* myComparator)(id, id, void *);
(This is just like block syntax, except blocks use ^
instead of *
)
Is it really necessary to store the pointer? Why not just include the .h with the function declaration, then pass in the reference to the function?
You can define the function pointer as a type (with typedef
) and then use it in your class definitions. For example
In a common header:
typedef NSInteger (*COMPARATOR)(id, id, void *);
In the first class:
@interface MyClass : NSObject {
NSObject *anotherField;
COMPARATOR thecomparator;
}
- (COMPARATOR)comparator;
- (void)setComparator:(COMPARATOR) cmp;
@end
And in the second class:
@interface MyOtherClass : NSObject {
NSObject *afield;
COMPARATOR thecomparator;
}
- (COMPARATOR)comparator;
- (void)setComparator:(COMPARATOR) cmp;
@end
The type COMPARATOR
is then used as any other type.
Edit: I add some methods to show how to pass and retrieve function pointer.
Function pointers are a little weird, because the name goes inside the type definition.
If you want to pass around a function pointer for a method like this:
- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context;
You would write a function like this:
NSInteger myComparisonFunction(id left, id right, void *context) {
// do stuff...
}
And a typedef like this:
typedef NSInteger (ComparisonFunc *)(id, id, void *);
Then in your class you can declare an instance variable like this:
ComparisonFunc compFunc;
And a property like this:
@property (nonatomic) ComparisonFunc compFunc;
Then to set the property you can call:
myObject.compFunc = myComparisonFunction;
And within myObject you can use it like this:
sortedArray = [array sortedArrayUsingFunction:compFunc context:NULL];
精彩评论