Introduction to Objective-C for Programmers, part II

Introduction to Objective-C for Programmers, part II

Introduction to Objective-C for Programmers contains the following parts already:

 

This is a continuation on the series ‘Introduction to Objective-C for Programmers’, in this part I’m going to show you a bit of magic with class cluster pattern – wildly used in iOS world, will write a bit on Catagories and a tiny bit on standard description method found in every NSObject.

Class Cluster Pattern

One of the first wildly used design patterns you will see when starting the Objective-C journey is the ‘Class Cluster’ pattern. This is basically a variation of GoF ‘Abstract Factory’, cited from the Apple iOS developer library:

Class clusters group a number of private concrete subclasses under a public ‘abstract’ superclass. The grouping of classes in this way simplifies the publicly visible architecture of an object-oriented framework without reducing its functional richness. Class clusters are based on the Abstract Factory design pattern.

A Factory (Cluster) is an ‘abstract’ class which with a minimal information given produces for us a specific concrete instance of a Cluster that satisfies the behaviour of the cluster family of objects described by the Cluster interface. As a simple example consider the foundation NSNumber class:

NSNumber *aChar = [NSNumber numberWithChar:’a’];
NSNumber *anInt = [NSNumber numberWithInt:1];
NSNumber *aFloat = [NSNumber numberWithFloat:1.0];
NSNumber *aDouble = [NSNumber numberWithDouble:1.0];

As you can see with properly chosen initializer you can get a specific object instance like a float, int or double which still adheres to the NSNumber public interface.
The only difference between the so called ‘Class Cluster’ and wildly known ‘Abstract Factory’ is that in the first case the factory itself will return objects belonging to the common type whereas in standard ‘Abstract Factory’ by definition it doesn’t have to be the case.

Categories

Categories in Objective-C is a simple and quite powerful concept, all it does is to allow you to divide you class behavior into separate sources. Although possible, you should never use it to override the methods in the class itself unless you really know what you are doing (eg. Swizzling). So in simple words, if you have a class with behaviour that can be splitted into separate sections, use categories.

E.g. Lets say we have an ‘Order’ class with methods like

addProduct, removeProduct, setTaxCode, setTaxAmount, setShippingAddress, setInvoiceAddress etc,

we could divide that methods into three categories:

(Product Related)
addProduct, removeProduct

(TaxRelated)
setTaxCode, setTaxAmount

(AddressRelated)
setShippingAddress, setInvoiceAddress

To use that concept in Objective-C we can do the following:

#import <Foundation/Foundation.h>;

@interface Order : NSObject
-(void)processOrder;
@end

Simple Order class with single method to process something.

#import "Order.h"

@implementation Order

-(void)processOrder{
NSLog(@"Process order");
}

@end

and first category class created for product related methods

Order+Product.h

#import "Order.h"

@interface Order (Product)
-(void)addProduct;
-(void)removeProduct;
@end

Order+Product.m

#import "Order+Product.h"

@implementation Order (Product)

-(void)addProduct{
NSLog(@"Add Product called");
}
-(void)removeProduct{
NSLog(@"Remove Product called");
}
@end

You should think about addProduct and removeProduct methods like methods of the Order class, they are just splitted into multiple source files.

Use the categories only to split up the behaviour, you should not add properties to the categories as its impossible for a category (except the class continuation category) to add instance variables to a class. Categories are not able to synthesize instance variables. There are some possibilities to overcome this problem but it will make your code base just more messy without real advantage gained.

Class continuation category

Class continuation category is a special kind of category declared without the name directly on the class implementation file with simple ‘()’.

Because the methods and properties declared inside the class continuation category are placed directly on the implementation file they become private to that class.

Example:

@interface ViewController ()
@property(weak, nonatomic) IBOutlet UILabel *someLbl;
@end

@implementation ViewController

- (void)viewDidLoad
{
[super viewDidLoad];
[self.someLbl setText:@"text"];
}
@end

Description Method

I have added a point on description method just because there is one peculiar thing associated with that functionality. We all know ‘description’ its like toString() in Java for example, its pretty straightforward, you will override it to suit your needs for logging for example. In Objective-C, there is one more similar method called ‘debugDescription’ which gets called when you invoke the print-object command while debugging your Objective-C application.

Example, lets say we have a class called SimpleObject

SimpleObject.h

#import <Foundation/Foundation.h>;

@interface SimpleObject : NSObject

@end

SimpleObject.m

#import "SimpleObject.h"

@implementation SimpleObject

- (NSString *)description{
return @"Description of SimpleObject";
}

- (NSString *)debugDescription{
return @"We are in debug mode, yay!";
}

@end

When you simple print that object with

SimpleObject *so = [[SimpleObject alloc]init];
NSLog(@”SO: %@”, so)

You will get ‘Description of SimpleObject’ of course, but when you set a breakpoint just after the object had been created and in the debug window you print the description of the so object, you will end up seeing ‘We are in debug mode, yay!’ string.
I’m not really sure about usefulness of that method but posted it as a little gem I’ve found while learning Objective-C.
 

Introduction to Objective-C for Programmers contains the following parts already:

Leave a Reply