tags:

views:

232

answers:

2

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?

+3  A: 

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.

Chuck
>>The problem here is that what you wrote isn't remotely the right way to define a category.<< Ok. Can you correct my example?
4thSpace
+1  A: 

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
Abizern
I tried to apply code from the link to what I have but I'm still getting an error: cannot find interface declaration for Person.
4thSpace
I've updated the answer showing how I would rewrite the interface and implementation files.
Abizern
Thanks. I'm not seeing the category benefit. Looks like Person can operate perfectly fine using the changeWebAddress method without needing anything from aCategory.
4thSpace
The benefit appears when you want to add methods to NSString, for which you don't have source code.
mouviciel
I agree, there is no benefit with this example. One reason is if you want to treat changeWebAddress as a private function. In this way you don't expose it in a header file, although Objective-C's dynamic nature means you can still call the method from anywhere.
Abizern
That kind of goes back to why you only see category examples used on the native classes such as NSString, NSArray, etc. and not custom classes.
4thSpace