If you don’t like reading, you can go directly yo my test project and play with code.
Sometimes we need to add some funtionality to existing classes. In objective-c we can easily do ti with Categories. There is 1 limitation — we can’t add instance variables in categories. When people face this problem they usually create a sublasses. But let’s see other option and why subclassing could be wrong choice.
Why not subclassing?
Ask yourself a question — Do you want every one to ble able to use your extension? Then subclassing in not the answer.
- You have to use a subclass if I want to use new functionality. You can’t use original class.
- Existing clients / code doen’t know anything abut new subclass and functionality
Example — If you make a subclass MyViewController of UIViewController, you can’t use new funtionality in UIViewController.
Good exemple here is a GoogleAnalytics iOS SDK. The idea is that every UIViewController should have ability to track page view. So google created a subclass of UIViewController and added functionality for automatic page view tracking. To use this funtionality you have to subclass not from UIViewController but from GAITrackedViewController. Here comes problem.
- I want to subclass for UITableViewController. I can’t subclass from both.
- I’m using some external library that doen’t know about GAITrackedViewController, example JASidePanelController.
Extending Existing class
When we extend existing class, all other classes can use our extention. For them there no difference between our extended functionality and original funtionality. We extend classes with Categories.
- We extend UIViewController with ability to track page views. Everyone who subclass from UIViewController has access to our funtionality to track page views.
But you will think — We can’t add instance variables in Categories. Actually, You can! You can do it with adding associated object to a class in runtime. It’s not so hard and scary. Let’s see an Example.
We have create AssociatedTest catory of NSObject
Here how would look implementation fur this class.
Just one line! In ASSOCIATED you need to pass: property name, setter name, property type, and memory rule (should it assigned, retained, copied and etc). But you would ask what is ASSOCIATED. I’ve made a simple macro for generatin getter and setter with associated oject for this property. You can find it here. If you don’t want to use an ASSOCIATED macro you can use my code snnipets to create getters and setters for your property —
Now can simple use our extended class property