开发者

I have a Objective C function that takes any type of object by reference. But when i pass a NSMutableArray My function does not recognise It

I have a function That takes by reference any kind of object -(BOOL)RemoteCall:(id**)DataClass; in the implementation i use [*DataClass isMemberOfClass:[NSMutableArray class] to find out the type of the object. The problem is it does not work with NSMUtableArrays Does anybody have a solution to this problem ? Here is the relev开发者_StackOverflowant code:

Implementation:

-(BOOL)RemoteCall:(id**)DataClass
{
    if([*DataClass isMemberOfClass:[NSMutableArray class] ] == YES)
    {
            NSMutableArray * SW =(NSMutableArray *)*DataClass;
                       //do something with SW
            DataClass= (id**)SW;
                        return TRUE;
    }
}

Any help and I mean anything at all will be appreciated, I'm stuck.

Method Call:
NSMutableArray * channelArray = [[NSMutableArray alloc]init]
Services * serv = [[Services alloc] init];
return [serv RemoteCall:&channelArray]; 


Pass by reference in Objective-C is almost never the right way.

There are a number of problems with that code.

  • (id**) is a pointer to a pointer to a pointer to an object. Probably not at all what you want.

  • YES and NO are BOOL return types; not TRUE

  • there is no reason in that code to be returning something by reference.

  • method names start with lower case letters. Arguments do, too.

  • There will never be an instance of NSMutableArray in an application; just subclasses

  • You can't tell the difference between a mutable and immutable array in the first place; check for isKindOfClass: or isMemberOfClass: for an NSMutableArray won't do you much good (it is useful, but misleading).

This is better:

-(BOOL)remoteCall: (id) dataThing
{
    if([dataThing isKindOfClass:[NSMutableArray class]] == YES)
    {
            NSMutableArray *swArray = dataThing; // not strictly necessary, but good defensive practice
            //do something with swArray
            return YES;
    }
    return NO;
}

To be called like:

NSMutableArray * channelArray = [[NSMutableArray alloc]init]; // you'll need to release this somewhere
Services * serv = [[Services alloc] init];
return [serv remoteCall:channelArray]; 

Since you don't return a different array in remoteCall:, channelArray's contents will be manipulated by the method and the YES/NO return value.

If there is some reason why the above seemingly won't work for you, please explain why.

Note: The code obviously requires an NSMutableArray if you are going to muck with the contents. The isKindOfClass: could be checking for NSMutableArray or NSArray and it wouldn't matter either way. When using arrays in your code and requiring a mutable array, it is up to you to make sure the data flow is correct such that you don't end up w/an immutable array where you need a mutable array.


If you don't need to reassign your variable, then don't use this. id or NSObject * is just fine and works by reference anyway. id * or NSObject ** would be references. id ** doesn't make sense at all here.

Also, learn naming conventions (like upper/lowercase).


NSArray is a class cluster. That means that every NSArray instance is actually an instance of some subclass. Only isKindOfClass: is useful for class-membership testing with class clusters.

Also... thats horrible code - please accept this:

-(BOOL)remoteCall:(id)dataClass {
    if([dataClass isKindOfClass:[NSMutableArray class]]) {
            NSMutableArray *sw =(NSMutableArray *)dataClass;
            return YES;
    }
}

that should work.

Constructive critisism of coding: You need to adhere to coding conventions. Although your code will work... its not brilliant to read and theres a lot of unnecessary *s and such.

Function names should be camel coded with a preceeding lower-case letter as should variable names. Passing (id) into a function doesn't require *s at all. Objects you pass into a function only available throughout the scope of the method anyway and that method doesn't own it, I'm not sure what you're trying to do with all the extra *s, but just treat objects you pass into the method as if you don't own them. :)


As Eiko said before, i'd use just id and not double pointers to ID.
I'm also pretty sure that isMemberOfClass is your Problem. isMember does not check for inheritance, so you're only asking for Top level Classes. isKindOfClass is probably the better choice, as there is no guarantee that Apple doesn't use an internal subclass of NSMutableArray internally. Check the Apple Docs. i'd write it as such:

-(BOOL)RemoteCall:(id)dataClass
{
   if([dataClass isKindOfClass:[NSMutableArray class] ] == YES)
   {
       NSMutableArray * SW =(NSMutableArray *)dataClass;
       //do something with SW
       return TRUE;
   }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜