lundi 8 octobre 2012

Category to override methods

If you regularly take a look at some forums, you may have encountered some Categories that are used to override existing methods. Especially currently with the new orientations' methods and the UINavigationController issue (see my article about that). In practice, override a method in a category seems to work well, but that's a very bad idea. This article will try to explain why.


Priority between categories


First thing that you should know
There is absolutely no way to define which category should have priority over an other one !
You could think "that's ok if i use categories to override Apple's methods". You're completely wrong ! Because most of a Cocoa class' code is written itself into categories.
For instance, the NSString original class contains only two public methods (length and characterAtIndex), and all the others methods are declared into categories (such as NSStringExtensionMethods, NSExtendedStringPropertyListParsing, NSStringPathExtensions, NSURLUtilities, etc.).
Currently, overriding an Apple's method within a category seems to work, but there is no warranty that it would work again in the future (for example in the next iOS version).

Invoke the original


An other important point
From your overrided method, you can't invoke the original implementation.
You may think that you don't need original implementation. That may be true currently, but you should think your code to be easily updated.
You should note that whether the original method is implemented in a category or not, calling the current method on super will call the superclass implementation or the original implementation. Since a method could be implemented in the original class under a specific version, and in a category under an other version, i really don't recommend you to try to call super in a overrided method.

Conclusions


So Categories are not aimed to override existing methods !

To achieve that there are different ways. The best one is to override the method in a subclass. If you can't do that (because you can't use a different class for example) you may use swizzle method, but it may be unsafe. (I will post an article about swizzle shortly, for the time being search on the web).

1 commentaire: