Pregunta

Say I have a class Parent and the child is Child1 and Child2.

I declare Parent+ParentCategory and then I declare a method:

-(void) Redraw;

Later I want the Redraw function of Child1 to be different than the Redraw function of Child2.

Can I declare Child1+Child1Category and then override the

-(void) Redraw

Can -(void)Redraw of Child1 call the function in the parent category?

Can that be done?

What would be good approach?

I know classes can inherit each other. I know protocol can extend each other. I wonder why category doesn't?

¿Fue útil?

Solución

I do not agree with the given answers:

A.: It is not true, that category's methods win against class' method. This is an implementation detail, but the behavior is not defined.

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.

B. But this does not matter. You neither define a method in a category that is defined in the class nor define a method in two clashing categories. The cit. simply does not apply to your case. It applies to something like this:

@interface A : NSObject
- (void)doSomething;
@end
@implementation A
- (void)doSomething {}
@end

@interface A (Addition)
- (void)doSomething;
@end
@implementation A (Addition)
- (void)doSomething {}
@end

If I understand you correct, you do not want to do this. You want something like that:

Base level:

@interface A : NSObject
@end
@implementation A
@end

@interface A (Addition)
- (void)doSomething;
@end
@implementation A (Addition)
- (void)doSomething {}
@end

This does not break the rule, because there is no method in the category, which is in the class.

Subclass level:

@interface B : A
@end
@implementation B
@end

@interface B (Addition)
- (void)doSomething;
@end
@implementation B (Addition)
- (void)doSomething {}
@end
  1. There is no clash on the level of B for the same reason as there is no clash on the level of A.

  2. Somebody might say, that there is a clash, because B inherits -doSomething from A. But this is no clash, because in this case a priority rule applies: Subclasses overwrite methods.

You can do that.

Edit:

You can check the problem simply by adding the method to the class. Would that compile? In the clashing case, it wouldn't. In your case, it would.

Otros consejos

I will replay with a cit. from this answer:

Lets just put it this way. Don't override methods using categories, period, ever, end of answer.

The reason of this is that while it is exactly known that a category's method always win against a class method (that is, if you implement a method in a category that's already declared in the class you are extending with the category the method of the category will be called.) when you have multiple category implementing the same method which implementation takes precedence is undefined

It is not wise to use category to do this. Categories add methods to the current class. If there are multiple methods with the same name, it will replace the old one (it is NOT an override). But unfortunately it is hard to say which one is replaced. Don't do it or you may get in trouble.

And you probably can not call the method in Parent from the child category. The most proper design here is a protocol.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top