4

I have a method that receives many different kinds of objects and decides what to do with them:

-(void)performAction:(NSObject *)myAction withItem:(Item *)myItem {

actionCount = -1;
NSLog(@"-- NEW ACTION ARRAY --");
if ([myAction isMemberOfClass:[Look class]]) {
    currentActionArray = [self createLookArray:(Look *)myAction item:myItem];
} else if ([myAction isMemberOfClass:[Use class]]) {
    currentActionArray = [self createUseArray:(Use *)myAction item:myItem];
} else if ([myAction isMemberOfClass:[Exit class]]) {
    currentActionArray = [self createExitArray:(Exit *)myAction item:myItem];
} else if ([myAction isMemberOfClass:[NSArray class]] ) {
    NSLog(@"--- CUSTOM ACTION --- %@", myAction);
    currentActionArray = (NSArray *)myAction;
} 
[self performNextAction];

}

One of four things is going to come through here: Look, Use, Exit or NSArray. The first three are sent off to become NSArrays, the last is already an NSArray.

Now, when I do pass an NSArray in here from elsewhere, like this:

    NSArray *myAction = [[NSArray alloc] initWithObjects:myAction1, myAction2, nil];
[controller performAction:myAction withItem:nil];

...the custom action is never called, because it reads myAction as an NSCFArray rather than an NSArray. When I try [myAction isMemberOfClass:[NSCFArray class]] it doesn't recognise the CF. The simple way to get it working at the moment is just to assume that anything not a Look, Use or Exit is an NSArray (get rid of the last else if, and just leave it as an else), but that seems sloppy to me.

Anyone know how I can deal with this?

Thanks, -k.

Kevin Beimers
  • 187
  • 1
  • 2
  • 10

3 Answers3

8

You can try using isKindOfClass: instead of isMemberOfClass:.

The first one will return YES for objects that are either instances of the class you send, or subclasses of it, as it may be the case for NSCFArray.

pgb
  • 24,813
  • 12
  • 83
  • 113
  • That did it. Forgot about that one. Thanks all. – Kevin Beimers Sep 17 '09 at 14:53
  • 4
    I think it is important to note that `NSArray`, `NSString` and many other classes are _class clusters_. Meaning that you never get an object of the specified class, but always a private subclass. Instead of a `NSArray` you will always get a `NSCFArray`, which is a subclass of `NSArray` that is also a till-free bridge to the `CFArrayRef` type from Core Foundation _(A low level framework underneath Cocoa that is not Objective-C)_. – PeyloW Sep 17 '09 at 16:02
3

Two possibilities worth considering:

Community
  • 1
  • 1
mouviciel
  • 66,855
  • 13
  • 106
  • 140
2

NSСFArray is subclass of NSMutable Array

You can use isKindOfClass to check it

if ([myAction isMemberOfClass:[Look class]]) {
    currentActionArray = [self createLookArray:(Look *)myAction item:myItem];
} else if ([myAction isMemberOfClass:[Use class]]) {
        currentActionArray = [self createUseArray:(Use *)myAction item:myItem];
} else if ([myAction isMemberOfClass:[Exit class]]) {
        currentActionArray = [self createExitArray:(Exit *)myAction item:myItem];
} else if ([myAction isKindOfClass:[NSArray class]] ) {
        NSLog(@"--- CUSTOM ACTION --- %@", myAction);
        currentActionArray = (NSArray *)myAction;
} 
oxigen
  • 6,263
  • 3
  • 28
  • 37