Sunday, July 21, 2013

Objective-C Categories

Categories allow you to add methods to existing classes. The category allows new methods to be added to an existing class.
  • Categories let you add application or domain specific methods to existing classes. It can be quite powerful and convenient.
  • The clue is in the restriction that categories only add methods, you can't add variables to a class using categories. If the class needs more properties, then it has to be subclassed.(edit: you can use associative storage, I believe).
  • Categories are a nice way to add functionality while at the same time conforming to an object oriented principle to prefer composition over inheritance.

                       One of favorite illustrations of Objective-c categories in action is NSString. NSString is defined in the Foundation framework, which has no notion of views or windows. However, if you use an NSString in a Cocoa application you'll notice it responds to messages like – drawInRect:withAttributes:.


                                      Steps to create Categories


Step 1: Create the Category

Now that your project is set up, let's create a category that adds additional functionality to the NSStringclass. Click File > New > File and choose a Cocoa Touch Objective-C category from the window. Click "Next." Name your category "RemoveNums" and select NSString from the "Category on" drop down menu (you may need to type this in manually). Click "Next" followed by "Create."



 Declare Category:









Step 2:Declare the Category Method:

Back in your Xcode project, click "NSString+RemoveNums.h" to view the new category's header file. Add the following code to the interface to declare the method.


#import

@interface NSString (removeNumbers)
{
    
}

- (NSString *)removeNumbersFromString:(NSString *)string;

@end

Implement the Category Method:


#import "NSString+removeNumbers.h"

@implementation NSString (removeNumbers)

- (NSString *)removeNumbersFromString:(NSString *)string
{
    /*--
     - Implemetation logic for new category method
     * This category method creates a NSCharacterSet of 0-9
     * It trims any occurences of number characters from the input string
     * It returns the new string value to the receiver
     --*/
    
    NSString *trimmedString = nil;
    
    NSCharacterSet *numbersSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
    
    trimmedString = [string stringByTrimmingCharactersInSet:numbersSet];
    
    return trimmedString;
}

@end

 First we define an NSCharacterSetof the numbers zero through nine which we'll use as a reference to compare against the original input string. In this case, the original string "Tekglintsoftsol iPhone Training 12345" will have the numbers "12345" removed from the string because the category method uses the NSString method stringByTrimmingCharactersInSet:.

my NSString+removeNumbers.h category .h and .m is over now i have created one class i.e 


MyClass 

After declaring the class i have imported Category into Myclass. the declaration is look like this 

#import "NSString+removeNumbers.h"

#import

@interface MyClass : NSObject
{
    
}

@end


After importing the Category i have created method declaration in Myclass interface .h

#import "NSString+removeNumbers.h"

#import

@interface MyClass : NSObject
{
    
}

-(NSString *)removeNumbersinString:(NSString *) string;

@end


MyClass Implementation .m 

#import "MyClass.h"

@implementation MyClass

-(NSString *)removeNumbersinString:(NSString *)string
{
    //Create the string
    
    NSString *stringWithNums =string;
    
    NSLog(@"stringWithNums         --> %@",stringWithNums);
    
    //Run string through category method
    
    stringWithNums = [stringWithNums removeNumbersFromString:stringWithNums];
    
    //Output trimmed string to the console
    
    NSLog(@"trimmed stringWithNums --> %@",stringWithNums);

    
    return stringWithNums;
}
@end

The above removeNumbersFromString is Category method whenever we use this method the original string "Tekglintsoftsol iPhone Training 12345" will have the numbers "12345" removed from the string because the category method uses the NSString method stringByTrimmingCharactersInSet:.

          After MyClass implementation is over now i am importing MyClass into main method and creating the MyClass object my code is shown below.

#import

#import "MyClass.h"


int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
        MyClass *myClassObject=[[MyClass alloc]init];
        
        
    }
    return 0;
}


Step 3:Test the Category 



#import

#import "MyClass.h"


int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
        MyClass *myClassObject=[[MyClass alloc]init];
        
        [myClassObject removeNumbersinString:@"Tekglint iPhone Training 12345"];
        
        
    }
    return 0;
}

 The local variablestringWithNums contains a combination of letters and numbers. The next line takes the string variable and runs it through the category method removeNumbersFromString. Finally, NSLog outputs the returned value of the newly trimmed string without any numbers.

Step 4:Run The Application

Click Product > Run, or click the "Run" arrow in the top left corner, to test the code. Notice the console shows the original input string, "Tekglint iPhone Training 12345" as well as the string after it has been altered by the category method and the numbers have been removed.

2013-07-22 12:37:33.118 RemoveNumbers[1062:303] stringWithNums         --> Tekglint iPhone

Training 12345

2013-07-22 12:37:33.128 RemoveNumbers[1062:303] trimmed stringWithNums --> Tekglint iPhone Training 


Step 5: Conclusion 

Subclassing is one way to add functionality to an object, but avoiding unnecessary subclassing by using a category will help reduce the amount of code and keep your projects more organized. There are a number of scenarios where using a category is beneficial.

No comments:

Post a Comment