Tuesday, September 15, 2015

Objective C isKindOfClass VS isMemberOfClass

We all know that NSObject is the base class in Objective c. Some times, We need to inherit the built in classes like NSArray, NSString and NSDictionary etc to add our required functionalities which are not given by those core classes. Like, I want an array which should give me all the elements by removing the duplicates if any. We can go for NSSet also for this feature. But, I need NSArray for a specific reason. In this case we need to write our own class which inherits from NSArray class. Suppose if I need that same functionality on NSString also, I need to create another sub class of NSString class.


                         



Instead of creating two separate sub classes for that similar functionality, We can write a method which accepts any data type as input, removes duplicates and returns the same data type as the return value.

Here is the method I am using to remove duplicates in NSArray or NSString.


- (id)removeDuplicates:(id)input{
    
    id output = nil;
    
    if([input isKindOfClass:[NSArray class]]){
        //loop array elements and remove duplicates and return an array
    }
    
    if([input isKindOfClass:[NSString class]]){
        //loop string characters and remove duplicates and return a string
    }
    
    return output;
    
}

If you observe, the input is of type id and output is of type id, which means any data type in Objective c. Here the point is how we can check whether the input is of type array or a string. In this case we can use NSObject's isKindOfClass to check whether the supplied input is of type NSArray or NSString. Based on the data type of the input, we can write that removing duplicates logic and return the result.

Now, let's see what is the use of NSObject's isMemberOfClass.

Let's say we have a Animal class. We have two sub classes of Animal class called Lion and Dog. I am not going to explain how to write such a classes as we are all much aware of that much object oriented programming using Objective c :)

 Lion *lion = [Lion alloc] init];  // Base class is Animal
 Dog *dog  = [Dog alloc] init];   // Base class is Animal


Let's say these animals have to make sound if they see their enemy. We all know that dogs bark and lions roar :). Let's say we have common method for that called 'makeSound'. 

- (id)makeSound:(id)input{    
      
    if([input isKindOfClass:[Lion class]]){
        [input roar];
    }    
    if([input isKindOfClass:[Dog class]]){
        [input bark];
    }      
}


In this case, like shown in the above code, if you use isKindOfClass, our dog is never gonna bark and our lion is never gonna roar :). It is because, isKindOfClass doesn't give you 'true' bool value for Lion and Dog classes. It will give you true value only if you write like the below code. But this always gives you roar sound though it's a dog or a lion.


- (id)makeSound:(id)input{    
      
    if([input isKindOfClass:[Animal class]]){
        [input roar];
    }    
    if([input isKindOfClass:[Animal class]]){
        [input bark];
    }      
}


Here comes isMemberOfClass, which gives true for immediate base class as shown in the below code.

- (id)makeSound:(id)input{    
      
    if([input isMemberOfClass:[Lion class]]){
        [input roar];
    }    
    if([input isMemberOfClass:[Dog class]]){
        [input bark];
    }      
}


Hope, you got an idea on the use cases of both isKindOfClass and isMemberOfClass and the difference between those two.



                         


Feel free to comment in case of any queries/concerns.