Reputation: 3520
I'm trying to create a factory (design pattern) in Objective C So I'm doing something like:
+ (Car *)createCar:(int)color {
if (color == 1) {
return [CarFactory createBlueCar];
} else if (color == 2) {
return [CarFactory createRedCar];
} else {
return nil;
}
}
+ (Car *)createBlueCar {
// ...
}
+(Car*)createRedCar{
// ...
}
However I don't want the createBlueCar
and the createRedCar
to be available to public and if I don't define them in the .h
file then I get a warning of the missing definition.
I'm a former Java developer and a newbie in Objective-C — So it might be just bad practice If so what the be good practice of doing so.
Upvotes: 27
Views: 15717
Reputation: 162722
The best way to do this is with a Class Extension.
.h
@interface MyClass : NSObject
@property(readonly) BOOL publiclyReadOnlyPrivatelyWritableFlag;
+ (id) myExposedFactoryMethod;
@end
.m
#import "MyClass.h"
@interface MyClass ()
@property(readwrite) BOOL publiclyReadOnlyPrivatelyWritableFlag;
+ (id) privateMethod1;
+ (id) privateMEthod2;
@end
@implementation MyClass
@synthesize publiclyReadOnlyPrivatelyWritableFlag; // no ivar -- only works in 64 bit and iPhone
+ (id) myExposedFactoryMethod
{
...
[self privateMethod1];
...
}
+ (id) privateMethod1;
{
return ...
}
+ (id) privateMEthod2;
{
return ...
}
@end
A class extension is a better solution because it is a true extension of the class's interface whereas a category (without a corresponding implementation) is merely a suggestion that the class implement the methods. That is, the compiler will warn if you don't implement the interface -- the methods -- declared in the class extension, but will not warn if you did the same with a named category.
Note also that a class extension allows you to upgrade a readonly
property to a readwrite
property as per the above example.
Upvotes: 49
Reputation: 523764
You can create a private static function
@implementation Car
static createBlueCar () {
....
}
+(Car*) createCar:(int) color{
if (color==1) {
return createBlueCar();
} ...
}
@end
but no, you cannot create a true private member. (You can invoke some conventions e.g. +(Car*)private_createCar
in a private category to discourage its use.)
Upvotes: -1
Reputation: 81330
I think you can add them to the class using an objective-c category within the implementation (not the interface) file as a way of emulating private methods if you want to "hide" them from users of your class.
Note, although you will no longer be advertising the methods to clients of your class, they will still be able to use them if they use the correct selectors. Additionally, they can always use something like classdump to regenerate the full interface to your class so your methods will never truly be hidden.
See this question for further examples of creating "private" methods under objective-c.
Upvotes: 4