Override a Method in Objective C via Category

Override a method in Objective c via category

Objective-C messaging is dynamic, this means that it doesn't matter if you import or not the category. The object will receive the message and execute that method.

The category is overriding your method. This means that when the runtime sends a message to that object, will always find the overridden method, no matter what you import.

If you want to ignore a category you shouldn't compile it, so you could remove the category from the compiler sources.

An alternative is subclassing.

Also read this:

Avoid Category Method Name Clashes

Because the methods declared in a category are added to an existing class, you need to be very careful about method names.

If the name of a method declared in a category is the same as a method in the original class, or a method in another category on the same class (or even a superclass), the behavior is undefined as to which method implementation is used at runtime. This is less likely to be an issue if you’re using categories with your own classes, but can cause problems when using categories to add methods to standard Cocoa or Cocoa Touch classes.

So in your case you haven't got any problem because as stated, this is less likely to happen with user defined classes. But you should definitely use subclassing instead of writing a category.

Is it possible to overwrite a category method in a category of the subclass?

From "Customizing Existing Classes"
in the "Programming with Objective-C" guide:

At runtime, there’s no difference between a method added by a category
and one that is implemented by the original class.

So the answer to your question is YES. There is no difference between overriding a method
in the subclass itself or in a category of the subclass. It makes also no difference if
the overridden method is implemented in the base class itself or in a category of the base class.

The only thing you cannot do is to use a category to override a method of the same class or of another category of the class.

Override a method via ObjC Category and call the default implementation?

If you want a hackish way to do this that involves mucking with the objective-c runtime you can always use method swizzling (insert standard disclaimers here.) It will allow you to store the different methods as arbitrariliy named selectors, then swap them in at runtime as you need them.

How do I properly override a class method in an Objective-C in a subclass?

It's technically ok.

I'd propose an alternative, though. If you already have a designated public initializer on your base class (which you might want to create and call from that factory class method anyway), and then use that very initializer (or even a new one from your subclass) in your subclasses' class method.

It's not much more code, but in my opinion easier to follow and future-proof. The initializer might come handy as well at one point, but of course it's not a solution for every application.

Override a method using a category, when that method was already defined in a category

As rmaddy said, what you're doing is not a good idea and will result in undefined behavior. You shouldn't try to override methods in a category. If you absolutely can't touch the existing code you can reasonably do one of 2 things.

  1. Subclass SomeDudesSuperClass and override the method there.

  2. Use method swizzling to swap the method implementation with your custom one instead of overriding. This also gives you the option of implementing this like a proper override and call the original implementation inside your custom method if you need to.

This article by Mike Ash has a very nice explanation of this.

Will a method overridden in a category always take precedence over the original implementation?

Assuming no other categories are in play other than the ones I create,
am I guaranteed that the implementation in my category will always be
the logic that is called as long as the header for it is imported from
somewhere?

I doubt it matters at all whether you import the category header or not. Headers are information for the compiler; categories are added to classes at run time, and the selection of which implementation is used for a given method happens at run time. More importantly...

From Objective-C Programming Guide:

If the name of a method declared in a category is the same as a method
in the original class, or a method in another category on the same
class (or even a superclass), the behavior is undefined as to which
method implementation is used at runtime. This is less likely to be an
issue if you’re using categories with your own classes, but can cause
problems when using categories to add methods to standard Cocoa or
Cocoa Touch classes.

(Emphasis mine.)

Given the use of the word undefined, I would say that the answer to the question is no, there are no guarantees about which implementation will be used when you re-implement an existing method in a category. Practically speaking, if the class is your own, then your category's method will most likely be selected, and I'd trust that to be reliable if it works in testing for a given version of the compiler and runtime.

Is it OK to override UIViewController methods on a category on UITableViewController

Overriding methods in a category is discouraged. See Overriding methods using categories in Objective-C

In my opinion it doesn't matter if this means overriding an inherited or class-defined method. Why should it make a difference? Why not subclass?



Related Topics



Leave a reply



Submit