我正在尝试创建一个只能通过工厂方法实例化的对象。我通过抛出异常来阻止使用init
(请参阅Creating a class with no init method)。但是这意味着我必须在工厂方法中创建一个新方法secretInit。
//Factory method
- (URLReqs *)buildURLReq:(NSString *)location
{
URLReqs *tmp=[[URLReqs alloc] secretInit];
tmp.str=location
return tmp;
}
- (id) secretInit{
return [super init];
}
这种方法很麻烦,虽然我们可以避免在头文件中声明secretInit,但仍有人可以访问它。有更好的解决方案吗?
一个想法是尝试直接在URLReqs的超级对象上调用init,而不是创建一个函数来执行它。
答案 0 :(得分:1)
你不想这样做,但有可能:
#include <objc/message.h>
@implementation MyClass
+ (id) factoryMethodWithParameter:(NSString *) someString;
{
struct objc_super instanceSuper;
id myInstance = [self alloc];
instanceSuper.receiver = myInstance;
instanceSuper.super_class = [self superclass];
// instanceSuper.class = [self superclass]; // use this line if the above doesn't compile
myInstance = objc_msgSendSuper (&instanceSuper, @selector(init));
//continue on setting up myInstance's ivars . . .
[myInstance setVariable:someString];
return myInstance;
}
- (id) init
{
self = [super init];
if (!self) return nil;
[self release];
[self doesNotRecogniseSelector:_cmd];
return nil;
}
@end
这样您就可以继续向init
的“超级”对象发送myInstance
条消息,但不允许任何人发送init
到MyClass
个实例
但要小心,尽管这是使用objc/*.h
中声明的标准运行时函数,但不要指望Apple保持此运行时API的一致性。
答案 1 :(得分:0)
答案 2 :(得分:0)
只有在头文件中引用它时才会公开它。
不,等等。我应该说另一种方式。没有更好的隐藏方法,而不是在头文件中声明它。 Objective-C中不存在私有方法。