Friday 20 May 2016

Category in Objective C


A category provides an easy way for you to modularize the definition of a class into groups or categories of related methods. It also gives you an easy way to extend an existing class definition without even having access to the original source code for the class and without having to create a subclass. 

For example: we have a class Fraction, which look like as:

#import <Foundation/Foundation.h> // Define the Fraction class

@interface Fraction : NSObject
 @property int numerator, denominator;

-(void) setTo: (int) n over: (int) d; 
-(Fraction *) add: (Fraction *) f; -(void) reduce;
-(double) convertToNum;
-(void) print; 

@end

If we want to crate a mathOps category that will include the method to perform math operation:

Steps are as follows:

We can create category in separate category file or in to the original file as  class in.

1) import the class for which you want to create a category.

#import Fraction.h

Even though this is an interface section definition, it is an extension to an existing one.Therefore, you must import the original interface section so that the compiler knows about the 
Fraction class (unless you incorporate the new category directly into the original Fraction.h header file, which is an option). 

2) add interface 
@interface Fraction(category_name)

// add methods here

-(Fraction *) add: (Fraction *) f;
-(Fraction *) mul: (Fraction *) f; 
-(Fraction *) sub: (Fraction *) f; 
-(Fraction *) div: (Fraction *) f; 

@end 

The category name is enclosed in parentheses after the class name. Notice that you don’t list the Fraction’s parent class here; the compiler already knows it from Fraction.h.Also, you don’t tell it about the instance variables .

3) 
You can put the definitions for all your methods into a single implementation section. That is, you could define all the methods from the interface section in Fraction.h plus all the methods from the MathOps category in one implementations section.

Alternatively, you could define your category’s methods in a separate implementation section. In such a case, the implementation section for these methods must also identify the category to which the methods belong. As with the interface section, you do this by enclosing the category name inside parentheses after the class name, like this: 

@implementation Fraction(category_name)

// code for category methods
@end

Remember that extending a class by adding new methods with a category affects not just that class, but all its subclasses as well. 

Class Extensions:
There is a special case of creating a category without a name, that is no name is specified between the ( and ).This special syntax defines what is known as a class extension.When you define an unnamed category like this, you can extend the class by defining additional instance variables.This is not allowed for named categories. Methods declared in an unnamed category are implemented in the main implementation section for the class and not in a separate implementation section.

Let’s assume we have a class called GraphicObject. Further assume we type the following lines into
our implementation file GraphicObject.m:

#import "GraphicObject.h"
// Class extension
@interface GraphicObject ()
 @property int uniqueID;
-(void) doStuffWithUniqueID: (int) theID;

 @end

@implementation GraphicObject 
@synthesize uniqueID;

(void) doStuffWithUniqueID: (int) myID
{
self.uniqueID = myID;
... }
...
// Other GraphicObject methods ...
@end

Unnamed categories are useful because their methods are private. So if you need to write a class that has data and methods that can only be used within the class itself, an unnamed category might just fit the bill.