假设ParentClass
有一个公共初始值设定项initWithSomething
:
-(id) initWithSomething: (NSString *)something;
现在在ChildClass
,我使用了这个初始化程序,但我不希望任何扩展ChildClass
的人都可以访问它。相反,我只希望他们能够访问我更具体的初始化程序initWithSomethingSpecific
。
因此GrandChildClass
只能访问initWithSomethingSpecific
,而不是initWithSomething
。
这在Objective-C中是否可行?
答案 0 :(得分:3)
要执行此操作,请使用
方法覆盖ParentClass
中的ChildClass
方法
要实现(1)您使用unavailable
属性,在ChildClass.h
中写下如下内容:
// prevent use of inherited initWithSomething outside of this implementation
- (instancetype) initWithSomething:(Something *)something __attribute__((unavailable("Use -initWithSomethingSpecific: instead")));
这将阻止Xcode在代码完成期间提供它,如果程序员仍然编写它将产生编译时错误,使消息使用initWithSomethingSpecific
。
要解决(2),您提供了调用NSObject
' doesNotRecognizeSelector:
的方法的实现。例如,在ChildClass.m
中写下类似的内容:
// prevent use of inherited initWithSomething outside of this implementation
- (instancetype) initWithSomething:(Something *)something
{
[self doesNotRecognizeSelector:_cmd]; // for any code which makes it here make it look like the method does not exist
return nil; // will never reach here
}
(_cmd
是每个Objective-C方法的标准隐藏参数,其值是方法本身的选择器。)
如果调用此方法,将生成未实现方法的常见错误和堆栈跟踪。
HTH
答案 1 :(得分:0)
不可能强制执行,不。您应该记录更具体的初始化程序的使用,并将其保留。如果您没有提供文档,请确保在头文件中对声明进行大量评论。
如果您能够在[ChildClass initWithSomething:]
中使用相同的方法签名,那么[ParentClass initWithSomething:]
的子类无法进入ChildClass
。
答案 2 :(得分:0)
您可以[ChildClass initWithSomething:]
返回nil
然后实施initWithSomethingSpecific
答案 3 :(得分:0)
我认为您正在寻找UNAVAILABLE_ATTRIBUTE
宏。
将此代码放在ChildClass
标题中:
- (instancetype)initWithSomething:(NSString *)something UNAVAILABLE_ATTRIBUTE;
另外,
如果您需要完全保护,可以在initWithSomething
中实施ChildClass
并提出异常。