Today lets see what is subclassing, categories and extensions in Objective C, and where, when and how to use these concepts.
Note: A complete working Xcode project copy is available for download, which includes all the required examples to understand these concepts practically at the end of this post.
1) Subclass in Objective C
Subclassing in simple words is changing the behavior of properties or methods of an existing class or in other words subclassing is inheriting a class and modifying the methods or properties of super class however you want.
Suppose for example consider a UITextField class, by default the placeholder text of UITextField will be of light gray color with default system font. If we want to change this style just subclass UITextField and override drawPlaceholderInRect method.
Example:
Create a class of type UITextField and name it some thing like CustomUITextFieldPlaceholderAppearance
CustomUITextFieldPlaceholderAppearance.h
#import <UIKit/UIKit.h>
@interface CustomUITextFieldPlaceholderAppearance : UITextField
@end
CustomUITextFieldPlaceholderAppearance.m
#import "CustomUITextFieldPlaceholderAppearance.h"
@implementation CustomUITextFieldPlaceholderAppearance
// override drawPlaceholderInRect method
- (void)drawPlaceholderInRect:(CGRect)rect {
// Set color and font size and style of placeholder text
[[UIColor redColor] setFill]; //set placeholder text color to red
[[self placeholder] drawInRect:rect withFont:[UIFont fontWithName:@"verdana" size:14.0]]; //set custom font style and size to placeholder text
}
@end
Now in your application wherever you want this custom look and feel for placeholder text of textfield you can just import this subclass header file (#import "CustomUITextFieldPlaceholderAppearance.h") and create an object of this class and you are done. In addition to this look and feel the default delegate methods and properties of UITextField will remain same.
2) Categories in Objective C
An Objective C category allows you add your own methods to an existing class.
Categories are also called as "informal protocols".
Suppose take an example, since Foundation Framework classes such as NSString, NSArray, NSDate etc… doesn’t have any access to modify, you can add your own methods in to these classes by the help of a category.
Consider NSString Class and if suppose we want to add a reverse string method to NSString class, so that in our application at any point of time any NSString object can call this category method and get a reversed string as a result. We can do this as below,
Note: Usually naming convention for category file is like OriginalClassName+CategoryName
Example:
Lets create a category class with a name something like NSString+NSString_ReverseString
NSString+NSString_ReverseString.h
#import <Foundation/Foundation.h>
@interface NSString (NSString_ReverseString)
- (NSString *)reverseString:(NSString *)yourString;
@end
NSString+NSString_ReverseString.m
#import "NSString+NSString_ReverseString.h"
@implementation NSString (NSString_ReverseString)
- (NSString *)reverseString:(NSString *)yourString
{
NSMutableString *reversedStr = [NSMutableString stringWithCapacity:[yourString length]];
[yourString enumerateSubstringsInRange:NSMakeRange(0,[yourString length])
options:(NSStringEnumerationReverse | NSStringEnumerationByComposedCharacterSequences)
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
[reversedStr appendString:substring];
}];
return reversedStr;
}
@end
Now in your application wherever you want to reverse a string then just import this category header file (#import "NSString+NSString_ReverseString.h"
) and call our reverseString: method from any of NSString object and it will reverse and return you the reversed string.
In the above example we have added a custom method called reverseString: to NSString class from the help of a category.
Note that in a category you can’t add an instance variable, since methods within a category are added to a class at runtime.
3) Extensions in Objective C
Extensions are similar to categories but the need of extension is different.
- Class extensions are often used to extend the public interface with additional private methods or properties for use within the implementation of the class.
- Extensions can only be added to a class for which you have the source code at compile time (the class is compiled at the same time as the class extension).
- Extensions will be local to a class file.
The syntax to declare class extension looks like,
@interface ClassName()
@end
since no name is given in the parentheses, class extensions are often referred to as anonymous categories.
Note Extensions can add instance variables.
Example:
@interface ABCExtension()
@property NSObject *yourProperty;
@end
the compiler will automatically synthesize the relevant accessor methods, as well as an instance variable, inside the primary class implementation.
If you add any methods in a class extension, these must be implemented in the primary implementation for the class.
Example:
In any of your class in implementation file(.m), say ViewController.m
@interface ViewController ()
-(void)printName:(NSString *)name;
@end
@implementation ViewController
-(void)printName:(NSString *)name
{
NSLog(@"%@",name);
}
In the above extension example printName: method is private to class ViewController, and cannot be accessed from outside the ViewController class.(even if you inherit since printName: is a private method their will not be any access to this method outside the class)
You can call this extension method only inside ViewController class, as below
[self printName:@"MyName"];
Usually people will use extensions to hide private information of a class without exposing them to access from any other class.
Finally few simple points to remember is
- Subclassing is better option if you want to customize an existing stuffs or functionalities, and
- Category is a best option if you want to add additional functionalities to an existing class
You can download a Sample Xcode Project here.
Hope this post was helpful, any comments or suggestions is acceptable.
Hope this post was helpful, any comments or suggestions is acceptable.
Thank you mr. Arun
ReplyDelete@Udimudi Hemaraju , My pleasure... :)
DeleteNice Explanation, Arun
ReplyDelete@Shivaji Pawar , Thank you... :-)
DeleteGreat one..
ReplyDelete@Daya Kevin, Thank you... :-)
DeleteHey Arun Superb.... Hope you remember me :)
ReplyDelete@Vinay Kumar Thanks maga, Hey of course maga I do remember :)
DeleteAwesome man....really impressed 😀
DeleteWhat happens if we override drawPlaceholderInRect:(CGRect)rect in category?
ReplyDeletewill it become again inheritance?
First thing is Category design pattern is to add your own custom methods for existing classes not to override methods. Secondly you are not allowed to override private methods of Apple predefined classes, it violates the basic principles of Apple and their are more chances of getting rejected in review of your app by Apple, if you do so.
DeleteHi Arun , Nice blog.
DeleteAs per your point(Secondly you are not allowed to override private methods of Apple predefined classes), my question is that we are overriding same in subclasses, how, is that something that subclasses allow us to add override private methods?
great tutorial man ...!!
ReplyDeleteMy pleasure buddy :) (y)
DeleteNice tutorial.....................
ReplyDeleteThank you :)
DeleteHi Arun, nice tutorial. But I have one doubt regarding subclass, in the above example you said to create an object of class "CustomUITextFieldPlaceholderAppearance". So is it enough if I just create an object like this , CustomUITextFieldPlaceholderAppearance *textField = [[CustomUITextFieldPlaceholderAppearance alloc] init]; ? and should i call a method of this class "drawPlaceholderInRect:(CGRect)rect" ?
ReplyDeleteHey, thanks man :), and coming to your doubt, you no need to call drawPlaceholderInRect method and it is not recommended as well.
DeleteYou just need to create an object of your subclass like "CustomUITextFieldPlaceholderAppearance *myTextField = [[CustomUITextFieldPlaceholderAppearance alloc] init];" and use this "myTextField" object.
Hope this clarifies your doubt.
Yep cleared my doubt and Thank you so much for the quick reply :)
Deletegreat, My pleasure :)
DeleteThis comment has been removed by the author.
ReplyDeleteHI Arun,
ReplyDeleteReally very nice sharing,you clear my all doubt.Thanks for sharing.
Sourabh
You are welcome @Sourabh :)
DeleteHi Arun, Its very clear.. Nice Explanation.. Please continue posting
ReplyDelete@Subhashini Mohan, Thanks a lot, sure I will try to keep posting more stuffs.
DeleteThanks.
ReplyDeleteHi,
ReplyDeleteI have a small question, here we are taking a new class that is NSString+NSString_ReverseString.h, without taking NSString+NSString_ReverseString.h , why can't we have a class method which does the same thing, what exact category role plays here? kindly explain.
Hi @bharathreddy vasipalli,
DeleteIf you implement the same functionality within a class as a class method, then the scope of "reverseString" method will be only within that particular class, you can’t use it as a generic “reverseString” method throughout your application.
But if you implement category pattern and add the additional methods to a existing Cocoa Touch class then the scope of that particular category methods is throughout your application.
By following these kind of patterns while you are developing your app the main advantage is your code will be independent of any entities, In other words - “loosely coupled” and flexible enough(easier) for future modifications or updations.
Hope I have clarified your doubt. Cheers :)
Arun@ Really it helps me a lot.. Thanks a ton.
Delete+Bharath Reddy, My pleasure :)
DeleteVery nice tutorial... good job. Can u please share something regarding protocols, encapsulation,polymorphism, with some examples, exactly in the same way as u did in this tutorial. Thanks in advance..
ReplyDeleteOnce again, i must say, superb tutorial.
@Amit Thakur, My pleasure :), Yup definitely will try to cover those topics soon.
DeleteJust fabulous.. Your examples help in remembering things for a long term.. :)
ReplyDelete@Anonymous, Thank you, My pleasure :)
DeleteGreat Arun
ReplyDeleteThank you :)
DeleteHi sir,
ReplyDeleteIt's very good tutorial. Thanks
Really greate tutorial arun
ReplyDeleteNice tutorial Aman thanks,
ReplyDeleteAre u in swift ? i want to learn it , can u help me out ?
Good work...Nice Tutorial.
ReplyDeleteAwesome work (y)
ReplyDelete"Subclassing in simple words is changing the behavior of properties or methods of an existing class or in other words subclassing is inheriting a class and modifying the methods or properties of super class however you want."
ReplyDeleteso - what is difference between subclassing and inheritance? ))
Architectural Consultant in Dubai
ReplyDeleteArchitectural Firms in Dubai
kayseriescortu.com - alacam.org - xescortun.com
ReplyDeletebusiness phone systems
ReplyDeleteonline casino
ReplyDelete10most.net
ReplyDeletefelnőttképzés
ReplyDeleteThis post is really very informative for us. Is a Turkey visa US citizens is necessary ? Yes, of course all the US citizens need a Turkish visa or evisa to enter Turkey. It is a necessary Turkish travel document.
ReplyDeleteképzés
ReplyDeleteMmorpg oyunları
ReplyDeleteİNSTAGRAM TAKİPCİ SATIN AL
TİKTOK JETON HİLESİ
tiktok jeton hilesi
Antalya sac ekimi
referans kimliği nedir
instagram takipçi satın al
metin2 pvp serverlar
instagram takipçi satın al
SMM PANEL
ReplyDeleteSmm Panel
iş ilanları
İNSTAGRAM TAKİPÇİ SATIN AL
Https://www.hirdavatciburada.com/
beyazesyateknikservisi.com.tr
SERVİS
JETON HİLE İNDİR
Nice post! This is a very nice blog that I will definitively come back to more times this year! Thanks for informative post.파주출장아로마
ReplyDelete평택출장아로마
화성출장아로마
의정부출장아로마
동해출장아로마
başakşehir
ReplyDeletebayrampaşa
beşiktaş
beykoz
beylikdüzü
KVFZ
mecidiyeköy
ReplyDeletesakarya
istanbul
kayseri
ordu
GWYV
sa
ReplyDeleteورنيش
ReplyDeleteبيتومين عازل