Reputation: 1398
I am trying to declare a private @interface
for a category, in the .m file.
For a normal class I would do:
@interface ClassA ()
@end
@implementation ClassA
@end
and it would work smoothly.
For a class with categories I tried:
@interface ClassA (CategoryA) ()
@end
@implementation ClassA (CategoryA)
@end
but it is giving all sort of different errors. I am trying to "extend" a category, the way that a class is extended via this syntax @interface ClassA ()
.
I want to have private methods for the category, and I wanted to know if, IN ADDITION to the exposed interface I am allowed to put a second category @interface
in the .m file, which does not expose instance variables and methods outside the class itself.
Something like this:
ClassA+categoryA.h
@interface ClassA (CategoryA)
<some public methods>
@end
ClassA+categoryA.m file
@interface ClassA (CategoryA)
<some private methods>
@end
@implementation ClassA (CategoryA)
<here I want to be able to call the private methods above>
@end
Right now this is giving me a warning in Xcode:
Duplicate definition of category 'CategoryA' on interface 'ClassA'
Is there any way to get this behavior?
Upvotes: 7
Views: 4082
Reputation: 64012
No, you can't declare two interfaces for a single category. You can do one of two things:
Englebert+Humperdinck.h
#import "Englebert.h"
@interface Englebert (Humperdinck)
- (void) croon;
@end
You can declare another category with a different name to contain the private methods. These can then be used in the same file where the private category interface is declared:
Englebert+Humperdinck.m
#import "Englebert+Humperdinck.h"
@interface Englebert (HumperdinckPrivate)
- (void) warmUp;
@end
@implementation Englebert (HumperdinckPrivate)
- (void)warmUp {
NSLog(@"Warm up");
}
@end
@implementation Englebert (Humperdinck)
- (void)croon {
[self warmUp];
NSLog(@"Croon");
// etc.
}
@end
The other option is to simply not declare the private methods. If you just define them in the implementation block, you can use them at any point in that file after they are defined (and for the latest version of Xcode/LLVM, the order is in fact unimportant -- undeclared methods can be used anywhere in the file in which they are defined). No other files will be able to see these methods.
Englebert+Humperdinck.m
#import "Englebert+Humperdinck.h"
@implementation Englebert (Humperdinck)
/* Undeclared private method */
- (void)warmUp {
NSLog(@"Warm up");
}
- (void)croon {
[self warmUp];
NSLog(@"Croon");
// etc.
}
@end
Upvotes: 14
Reputation: 20431
@interface ClassA ()
is an anonymous category, and you can use these as interfaces and define the implementation in the ClassA
implementation as well. @interface ClassA (CategoryA) ()
is a syntax error and should read @interface ClassA (CategoryA)
EDIT:
To create private methods for a class, in that class' .m
file you would have:
@interface ClassA ()
// Private functions declared
@end
@implementation ClassA
// Private functions defined
// Other functions defined
@end
The same can be done for named categories, however you will need to define the implementation separately to avoid warnings. Again, in the .m
file:
@interface ClassA (hidden)
// Private functions declared
@end
@implementation ClassA (hidden)
// Private functions declared
@end
@implementation ClassA
// Other functions defined
@end
Upvotes: 0
Reputation: 10124
Do
@interface ClassA (CategoryA)
@end
@implementation ClassA (CategoryA)
@end
Instead. Categories can't have instance varibles. And what kind of errors are you talking about?
Upvotes: 1