When to use Categories - objective-c

I've recently discovered categories and was wondering when it might be appropriate to use them in a user defined class/new class. For example, I can see the benefits of adding a category to an existing class like NSString, but when creating a new class what would be the advantage of adding a category to this rather than just implementing a normal method?
Hope this makes sense.
Many thanks
Jules

The answer isn't really any different for your own classes than it is for framework classes. If you have multiple projects, you'll likely end up sharing some classes between them. However, you may want to extend some of your classes so that they work more easily with a specific project, but not want to include those extra methods in your other projects, where they might not make sense. You can use a category to extend your class without needing to subclass.

If I understand your question correctly, creating a "new class" is always "subclassing" because you're subclassing NSObject at the very least.
You could use categories on a new class to separate out sections of responsibility of a complex class. For example, all the basic functionality (instance variables, accessors, description, etc.) can go in one file (the "main" class file) while all methods to support a protocol (such as NSTableViewDataSource) can go in another.
Some take this approach to keep things "neat". I'm a firm believer in "if it's my own custom class, all its code should be in one file" so I do not personally do this. I demarcate different logical aspects of the class' code with "#pragma mark Some Section Name" to help navigation and readability. Your mileage may vary.

Adding a Category on NSString is useful when you want to call a method on every single NSString instance you will encounter. This is a real improvement over inheritance for this kind of object because they are used by the core framework and you don't have to convert a NSString object to your subclass when you want to call your custom method.
On the other hand, you can just put methods in, no instance variables.

In the book Refactoring by Martin Fowler, he has a section titled "Introduce Foreign Method" (A server class you are using needs an additional method, but you can't modify the class.) That's what categories are good for.
That said, there are times when using a category, instead of changing the class, is appropriate. A good example on using a category, even though you could change the server class, is how Apple handled the UIViewController MediaPlayer Additions. They could have put these two methods in UIViewController itself but since the only people who would ever use them are people who are using the Media Player framework, it made more sense to keep the methods there.

Related

Choosing a Singleton or a Category?

Fairly early on in my app, when I was a lot less experienced than I am now, I wanted to spice up some transitions between view controllers with my own custom animations. Having no idea where to start, I looked around SO for a pattern like MVC that could be accessed from nearly any controller at any time, and as it turns out, a singleton was the way to go.
What I didn't realize is that there seems to be a strong and well-defended hatred of the singleton pattern, and I myself am starting to see why, but that is beside the point.
So, a while later, I decided to move my very same implementation into a category on UINavigationController (after all, it handles transitions!), kept the original classes around for comparison, and am wondering which method would work best. Having thoroughly tested both implementations, I can say without a doubt that they are equal in every way, including speed, accuracy, smoothness, frame-rate, memory usage, etc. so which one is 'better' in the sense of overall maintainability?
EDIT: after reading the well-written arguments you all have made, I have decided to use a singleton. #JustinXXVII has made the most convincing argument (IMHO), although I consider every answer here equally worthy of merit. Thank you all for your opinions, I have upvoted all answers in the question.
I believe the best option is use the category.
Because if you are already using UINavigationController, do not make sense create a new class that will only manage the transition, like you told: (after all, it handles transitions!)
This will be a better option to maintain your code, and you will be sure that the thing do what they expect to do, and if you already have an instance that do the transitions, why create another?
The design patterns, like singleton, factory, and others, need to be used with responsibility. In your case, I do not see why use a singleton, you use it only to no instantiate new objects, you do not really need to have only one instance of it, but you do it because you want only one.
I'll make the case for a singleton object. Singletons are used all over UIKit and iOS. One thing you can't do with categories is add instance variables. There are two things about this:
MVC workflows don't tolerate objects with intimate knowledge of other objects
Sometimes you just need a place to reference an object that doesn't really belong anywhere else
These things go against each other, but the added ability to be able to keep an instance variable that doesn't really have an "owner" is why I favor the singleton.
I usually have one singleton class in all of my XCode projects, which is used to store "global" objects and do mundane things that I don't want to burden my AppDelegate with.
An example would be serializing/archiving objects and unarchiving/restoring. I have to use the same method throughout several classes, I don't want to extend UIViewController with some serializing method to write and read arbitrary files. Maybe it's just my personal preference.
I also might need a quick way to lookup information in NSUserDefaults but not want to always be writing [[NSUserDefaults standardUserDefaults]stringForKey:#"blah"], so I will just declare a method in my singleton that takes a string argument.
Until now i've not really thought too much about using a category for these things. One thing is sure though, I'd rather not be instantiating a new object a hundred times to do the same task when I can have just one living object that sticks around and will take care of stuff for me. (Without burdening the AppDelegate)
I think that the real question is in "design" (as you said, both codes work fine), and by writing down your problem in simple sentences, you will find your answer :
singleton's purpose is to have only one instance of a class running in your app. So you can share things between objects. (one available to many objects)
category purpose is to extend the methods available to a class. (available to one class of objects only ! ok...objects from subclasses too)
what you really want is to make a new transition available to UINavigationController class. UINavigationController, which has already some method available to change view (present modal views, addsubviews, etc.) is built to manage views with transitions (you said it yourself, it handles transitions), all you want to do is adding another way of handling transitions for your navigation controllers thus you would preferably use a category.
My opinion is that what you want to achieve is covered by the category and by doing this you ensure that the only objects which are accessing this method are entitled to use it. With the singleton pattern, any object of any class could call your singleton and its methods (and... it could work nobody knowing how for an OS version n but your app could be broken in n+1 version).
In this implementation, for which there is no need to use a Singleton, there may be no difference at all. That doesn't mean that there isn't one.
A plastic bucket holds as much water as a metal bucket does, and it does it just as well. In that aspect there seems to be no difference between the two. However, if you try to transport something extremely hot, the plastic bucket might not do the job so well..
What I'm trying to say is, they both serve their purposes but in your case there seemed to be no difference because the task was too generic. You wanted a method that was available from multiple classes, and both solutions can do that.
In your case, however, it might be a whole of a lot simpler to use a Category. The implementation is easier and you (possibly) need less code.
But if you were to create a data manager that holds an array of objects that you ONLY want available at one place, a Category will not be up to the task. That's a typical Singleton task.
Singeltons are single-instance objects (and if made static, available from nearly everywhere). Categories are extensions to your existing classes and limited to the class it extends.
To answer your question; choose a Category.
*A subclass might also work, but has its own pros and cons
Why don't you simply create a base UIViewController subclass and extend all of your view controllers from this object? A category doesn't make sense for this purpose.
Singletons, as the name suggests, has to be used when there is a need to be exactly one object in your application. The pattern for the accessor method ensures only this requirement being a class method:
+ (MyClass*) sharedInstance
{
static MyClass *instance = nil;
if (instance == nil) instance = [[MyClass alloc] init];
return instance;
}
If implemented well, the class also ensures that its constructor is private thus nobody else can instantiate the class but the accessor method: this ensures that at any time at most one instance of the class exists. The best example of such class is UIApplication since at any time there might be only one object of this class.
The point here is that this is the only requirement towards singleton. The role of the accessor method is to ensure that there is only one instance, and not that it would provide access to that instance from everywhere. It is only a side effect of the pattern that, the accessor method being static, everybody can access this single object without having a reference (pointer) to it a priori. Unfortunately this fact is widely abused by Objective C programmers and this leads to messed up design and the hatred towards singleton pattern you mentioned. But all in all it is not the fault the singleton patter but the misuse of their accessor method.
Now turning back to your question: if you don't need static / global variables in your custom transition code (I guess you don't) then the answer is definitely go for categories. In C++ you would subclass from some parent BaseTransition class and implement your actual drawing methods. Objective C has categories (that in my opinion is another way that easily messes up the design, but they are much more convenient) where you can add custom functionality even accessing the variables of your host class. Use them whenever you can redeem singletons with them and don't use singletons when the main requirement towards your class is not that it would be only one instance of it.

What's the name of the design pattern that makes a part of a class reusable.

I'm doing Objective-C for iOS, say I have several UIViewControllers.
Some of these view controllers will have a particular feature that I developed and I want to be able to reuse it easily.
The feature in question consists of two methods that use an instance variable of the UIViewController.
In Objective-C, it's similar to a category but that could be used theoretically with any kind of class.
I know this is not very clear but any help is appreciated.
You might be able to implement your functionality as a decorator using the decorator pattern.
You can subclass UIViewController, creating a custom UIViewController (say "sub1"). Then all of the UIViewControllers that need that functionality can subclass sub1. This way you can easily reuse the code written once for sub1 simply using inheritance.
...The feature in question consists of two methods... that could be used theoretically with any kind of class.
well without knowing more details I'd say Extract Class looks generally worth considering. For particular use cases, more specialized ones might be better fit than that (Strategy, Specification etc etc etc)

Share code between classes in Objective-C without inheritance?

Since Objective-C does not support multiple inheritance, is there some other mechanism to share code between classes?
I'm writing a Cocoa library on top of an existing xml schema. Many elements in the schema (for example, ) are used in multiple types. I was hoping to centralize this somehow, so that I didn't have to add #property NSString *name and the associated code to generate the xml for the name property in every single class that has a name attribute. That would be fairly straightforward if multiple inheritance were supported, but I don't know how to do it otherwise.
The best thing I can think of is to create a common superclass that has a superset of methods to encode each optional property, then call the appropriate methods (i.e. encodeName) in the encoding method for each class. Does that seem like the best way to go?
I would recommend you create a new Category with your properties/functions etc and add said category to NSObject. That would make all properties and functions available to all subclasses of NSObject. It's not exactly multiple inheritance but provides a great amount of flexibility.
It is actually possible to add data to a class at run time using the runtime's Associative Reference functions. It's a little deeper than normal SDK work, but works quite well. It's not the same as a full property with getters and setters, but it does associate objects with an instance.
If the methods are only required on certain objects then maybe a sub class from that class is the way to go or a category on that specific class would be better. The category on NSObject is quite a wide net to cast.
If you want to add additional state then sub classing is probably your safest bet.
If you do add a category make sure you prefix your methods with something unique so to avoid any conflicts. E.g. PSMySpecialMethod as opposed to mySpecialMethod

Objective-C category compared to Mixins

Is the concept of the Objective-C categories in anyway similar to the concept of mixins? If so: what are the similarities? In not: what are the differences?
To the best of my understanding:
Mixins
Syntactic sugar for composition
Added by the developer of the class, not the user
Can be reused by multiple classes
Can add instance variables
Can be implemented using forwarding in Objective-C
Categories
Similar to extension methods in other languages
Usually added by the user of the class, not the developer
Used by exactly one class and its subclasses
Can't add instance variables
To be clear the answer is NO - they are not the same.
The differences are outlined by John Calsbeek in the accepted answer, but I would say the key difference is the one where mixins can be used in different classes, whereas categories always extend exactly one class - which they declare in their definition.
This is the key difference because it means the use cases for these two features are utterly different. Another way of looking at it is that, if you're coming from Ruby to Objective-C and missing your mixins, you won't find any joy with categories.
The use case for mixins is that you have some code - methods and instance variables - that you want to reuse in several classes that don't have a common superclass. You can't do that with categories.
Mixins are effectively "multiple-inheritance" of the type you don't find in Objective-C. The closest thing in objective-c is protocols, just as the closest thing Java is interfaces, but they have neither instance variables nor method bodies (in objective-C or java). So you're generally left with creating helper classes or putting code in superclasses.
The use case for objective-c categories is that you want to add methods to an existing class - even a system or library class.
I would say that mixins are more powerful, but since it's an apples-to-oranges comparison, it would be pointless.
To be accurate:
the Ruby equivalent of Categories, is to simply reopen the class you want to extend and extend it. (You can do that anywhere in Ruby, and it's effectively identical to Categories)
I'm not sure what the objective-c equivalent to Mixins is though - anyone?
[Update] A bit more searching, and no there isn't an equivalent of Mixins in Objective-C, but the enterprising Vladimir Mitrovic has created a library that effectively does it. https://github.com/vl4dimir/ObjectiveMixin
I'm in two minds as to whether to use it or not: sometimes if the language you're using doesn't support something, it's easier to work with it rather than fight it or try to import your favourite features from other languages. ("If you can't be with the programming language you love, love the one you're with").
Then again, perhaps that's just a bit to snooty of me. The whole Aspect Oriented Programming movement has been glomming features onto Java for years (but never gaining much traction, I might add, outside of JBoss). Anyway, Vladimir gets extra kudos for using Ninja Turtles in his example.
On another side node: as a relative objective-c noob, it seems to me that categories are way overused in sample code I find all over the web. It seems common practice to add static helper methods to system classes with categories, when it would be just as easy to create a helper class to house those methods in your project, with less risk of them breaking when the system class is updated or you import someone else's library with their own such categories. A common example is adding new static color methods to UIColor. Why not just add them to a local class?
The one really good use I've seen for categories is adding methods, not to system classes, but to generated classes. So when you generate classes from your core-data object model, and you want to add new constructors or other methods that really do belong in the model class, you can do it with categories, allowing you to safely regenerate the model class if you change your model, without losing your work.
In summary:
- forget about categories as a solution for mixins
- categories are good for core-data but overused and overrated otherwise
Categories are defined for a particular class, as far as I know, you can't create a category and add the methods it implements to several classes.
With a mixin, you might derive a new class from your base and the mixin, then instantiate this new class to take advantage of it.
With a category, you are effectively adding directly the base class, so that all instances of that base have access to the functionality provided by the category.

What is the difference between inheritance and Categories in Objective-C

Can some one explain to me the difference between categories and inheritance in Objective C? I've read the entry in Wikipedia and the discussion on categories there doesn't look any different to that of inheritance. I also looked at the discussion on the topic in the book "Open iPhone Development" and I still don't get it.
Sometimes, inheritance just seems like more trouble than it is worth. It is correctly used when you want to add something to an existing class that is a change in the behaviour of that class.
With a Category, you just want the existing object to do a little more. As already given, if you just want to have a string class that handles compression, you don't need to subclass the string class, you just create a category that handles the compression. That way, you don't need to change the type of the string classes that you already use.
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.
Edit January 2012
Things have changed now. With the current LLVM compiler, and the modern, 64-bit runtime, you can add iVars and properties to class extensions (not categories). This lets you keep private iVars out of the public interface. But, if you declare properties for the iVars, they can still be accessed / changed via KVC, because there is still no such thing as a private method in Objective-C.
Categories allow you to add methods to existing classes. So rather than subclass NSData to add your funky new encryption methods, you can add them directly to the NSData class. Every NSData object in your app now has access to those methods.
To see how useful this can be, look at: CocoaDev
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:.
AppKit defines a category for NSString that provides additional drawing methods. The category allows new methods to be added to an existing class, so we're still just dealing with NSStrings. If AppKit instead implemented drawing by subclassing we'd have to deal with 'AppKitStrings' or 'NSSDrawableStrings' or something like that.
Categories let you add application or domain specific methods to existing classes. It can be quite powerful and convenient.
If you as a programmer are given a complete set of source code for a code library or application, you can go nuts and change whatever you need to achieve your programming goal with that code.
Unfortunately, this is not always the case or even desirable. A lot of times you are given a binary library/object kit and a set of headers to make do with.
Then a new functionality is needed for a class so you could do a couple of things:
create a new class whole instead of a stock class -- replicating all its functions and members then rewrite all the code to use the new class.
create a new wrapper class that contains the stock class as a member (compositing) and rewrite the codebase to utilize the new class.
binary patches of the library to change the code (good luck)
force the compiler to see your new class as the old one and hope it does not depend on a certain size or place in memory and specific entry points.
subclass specialization -- create subclasses to add functionality and modify driver code to use the subclass instead -- theoretically there should be few problems and if you need to add data members it is necessary, but the memory footprint will be different. You have the advantage of having both the new code and the old code available in the subclass and choosing which to use, the base class method or the overridden method.
modify the necessary objc class with a category definition containing methods to do what you want and/or override the old methods in the stock classes.
This can also fix errors in the library or customize methods for new hardware devices or whatever. It is not a panacea, but it allows for class method adding without recompiling the class/library that is unchanged. The original class is the same in code, memory size, and entry points, so legacy apps don't break. The compiler simply puts the new method(s) into the runtime as belonging to that class, and overrides methods with the same signature as in the original code.
an example:
You have a class Bing that outputs to a terminal, but not to a serial port, and now that is what you need. (for some reason). You have Bing.h and libBing.so, but not Bing.m in your kit.
The Bing class does all kinds of stuff internally, you don't even know all what, you just have the public api in the header.
You are smart, so you create a (SerialOutput) category for the Bing class.
[Bing_SerialOutput.m]
#interface Bing (SerialOutput) // a category
- (void)ToSerial: (SerialPort*) port ;
#end
#implementation Bing (SerialOutput)
- (void)ToSerial: (SerialPort*) port
{
... /// serial output code ///
}
#end
The compiler obliges to create an object that can be linked in with your app and the runtime now knows that Bing responds to #selector(ToSerial:) and you can use it as if the Bing class was built with that method. You cannot add data members only methods and this was not intended to create giant tumors of code attached to base classes but it does have its advantages over strictly typed languages.
I think some of these answers at least point to the idea that inheritance is a heavier way of adding functionality to an existing class, while categories are more lightweight.
Inheritance is used when you're creating a new class hierarchy (all the bells and whistles) and arguably brings alot of work when chosen as the method of adding functionality to existing classes.
As someone else here put it... If you are using inheritance to add a new method for example to NSString, you have to go and change the type you're using in any other code where you want to use this new method. If, however, you use categories, you can simply call the method on existing NSString types, without subclassing.
The same ends can be achieved with either, but categories seem to give us an option that is simpler and requires less maintenance (probably).
Anyone know if there are situations where categories are absolutely necessary?
A Category is like a mixin: a module in Ruby, or somewhat like an interface in Java. You can think of it as "naked methods". When you add a Category, you're adding methods to the class. The Wikipedia article has good stuff.
The best way to look at this difference is that:
1. inheritance : when want to turn it exactly in your way.
example : AsyncImageView to implement lazy loading. Which is done by inheriting UIView.
2. category : Just want to add a extra flavor to it.
example : We want to replace all spaces from a textfield's text
#interface UITextField(setText)
- (NSString *)replaceEscape;
#end
#implementation UITextField(setText)
- (NSString *)replaceEscape
{
self.text=[self.text stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceCharacterSet]];
return self.text;
}
#end
--- It will add a new property to textfield for you to escape all white spaces. Just like adding a new dimension to it without completely changing its way.