Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective C - Categories and Inheritance - Add method to base and add override to derived class

I know that categories should not be used to override a method in the class they are extending. However, what about the following scenario.

Consider the classes:

Base.h

#import <Foundation/NSObject.h>

@interface Base: NSObject { NSNumber *n; }
@end

Derived.h

#import "Base.h"

@interface Derived: Base { NSString *s; }
@end

With categories:

Base+Serialize.h

#import "Base.h"

@interface Base (Serialize)
- (NSString*)serialize;
@end

Base+Serialize.m

#import "Base+Serialize.h"

@implementation Base (Serialize)
- (NSString*)serialize
{
    return [NSString stringWithFormat:@"%@", n];
}

@end

Derived+Serialize.h

#import "Derived.h"

#import "Base+Serialize.h"

@interface Derived (Serialize)
- (NSString*)serialize;
@end

Derived+Serialize.m

#import "Derived+Serialize.h"

@implementation Derived (Serialize)
- (NSString*)serialize
{
    return [NSString stringWithFormat:@"%@, %@", s, [super serialize]];
}

@end

Obviously, this is a contrived/simplified example. But it works well to demonstrate what I would like to do. Essentially, I want to provide additional functionality to multiple classes in an inheritance hierarchy.

Is this a safe/valid use of categories? Any gotchas?

like image 739
kloffy Avatar asked Feb 23 '12 15:02

kloffy


1 Answers

This is an acceptable way to use categories. Categories do actually add the message to the class, so the message will work just like any other message. This includes inheritance.

Perhaps one thing to watch out for is that you can run into name collisions. I don't know how the runtime handles them, but if two categories supply the same message you may have unexpected behavior since the message you expect is not being called. That being said, you may just want a name which is a little more distinctive than serialize, unless of course, you need that name (e.g. you have an informal protocol).

like image 99
David V Avatar answered Sep 26 '22 07:09

David V