4thSpace
4thSpace

Reputation: 44352

Can categories be created only on Objective-C classes?

All of the examples of categories that I've seen use some Objective-C class rather than a custom class. For example: NSMutableArray, NSArray, NSString. I'd like to create a category for a custom class. Here's a useless example I created just to test but fails compilation:

//person.h
@interface Person (aCategory) : NSObject {
NSString *MyName;
NSString *webAddress;
}
@property(nonatomic, retain) NSString *MyName;
@end

//person.m
#import "Person+aCategory.h"

@implementation Person
@synthesize MyName;
@end

And the category definition:

@interface aCategory : NSObject {
NSString *webAddress;
}
@property(nonatomic, retain) NSString *webAddress;
- (void)changeWebAddress;
@end

//in aCategory.h
#import "aCategory.h"

@implementation aCategory
@synthesize webAddress;

- (void) changeWebAddress{
self.webAddress = @"http://www.abc.com";
}
@end

This will give the following errors and warning:

error: Person+aCategory.h: no such file or directory
warning: cannot find interface declaration for Person
error: no declaration of property 'MyName' found in interface

Is there a way to do this?

Upvotes: 1

Views: 746

Answers (2)

Abizern
Abizern

Reputation: 150715

You can create a category on any Objective-C class. Usually, the examples show categories on the NS Classes because you aren't usually able to change the class directly, which is something you would do if you had the source code to the class.

I usually use Categories on my own classes for the private methods, but I don't create a separate class for them, I just declare the @interface of the category in the .m file.

Here's a link to an answer which summarises the use of categories.

Following the comment, This is one way to rewrite the code:

//person.h
@interface Person : NSObject {
    NSString *myName;
    NSString *webAddress;
}
@property(nonatomic, copy) NSString *myName;
@property(nontatomic, copy) NSString *webAddress;
@end

//person.m
#import "Person.h"

@interface Person (aCategory)
- (void)changeWebAddress;
@end

@implementation Person
@synthesize myName;
@synthesize webAddress;
@end

@implementation Person (aCategory)
- (void)changeWebAddress {
    self.webAddress = @"http://www.abc.com";
}
@end

Upvotes: 1

Chuck
Chuck

Reputation: 237110

A custom Objective-C class you define is still an Objective-C class. You can create categories on them, yes. The problem here is that what you wrote isn't remotely the right way to define a category.

First you define a plain class. You put all your instance variables and whatever methods you want in there.

Then you define a category, which adds methods to the class it's on. Categories do not descend from any parent class or have ivars, because they just add methods to an existing class.

See Apple's The Objective-C Programming Language for full documentation.

Upvotes: 3

Related Questions