在设计类层次结构时,有时子类添加了一个新的initWithSomeNewParam
方法,并且希望禁用对从超类继承的旧init
方法的调用。
首先,我已经阅读了问题here,其中建议的替代方法是覆盖init
以在运行时抛出异常,或覆盖并设置属性的默认值。在我的情况下,我不想提供默认值,我想清楚地表明不应该调用旧方法,而是应该使用带参数的新方法。
因此运行时异常很好,但除非调试代码,否则团队中的其他程序员无法注意到旧方法不再用于使用。
如果我没错,就无法将方法标记为“私有”。所以,除了添加评论之外,有没有办法做到这一点?
提前致谢。
答案 0 :(得分:105)
您可以在头文件中明确标记init
不可用:
- (id) init __unavailable;
或:
- (id) init __attribute__((unavailable));
使用后面的语法,您甚至可以给出一个理由:
- (id) init __attribute__((unavailable("Must use initWithFoo: instead.")));
如果有人试图调用它,编译器会发出错误(而不是警告)。
答案 1 :(得分:4)
要添加@DarkDust发布的内容,您还可以使用UNAVAILABLE_ATTRIBUTE
- (id)init UNAVAILABLE_ATTRIBUTE;
当用户尝试在此类的实例上调用init
时,这将引发错误。
答案 2 :(得分:1)
标记它已被弃用? 开发人员将是开发人员,你无法阻止我们所有人! ; - )
答案 3 :(得分:0)
initWith:Stuff和:OtherStuff永远不应该是方便构造函数。
因为他们应该有效地致电
self = [self init];
if(self)
{
self.stuff = Stuff;
self.other = OtherStuff;
}
所以[object init]将始终返回一个处于预定义状态的对象,[object initWithStuff:stuff]将返回处于预定义状态的对象,并覆盖了一些东西。
基本上我得到的是,不好的做法是阻止[object init],特别是当某人将来继承你的子类时......
答案 4 :(得分:0)
语法已缩短为:
- (instancetype)init NS_UNAVAILABLE;
答案 5 :(得分:-1)
您可以通过为您的班级定义private extension来排序将某个方法标记为“私有”。
在你的.h:
@interface MyClassName
- (void)initWithSomeNewParam:(id)param;
在你的.m:
@interface MyClassName ()
- (void)init;
@end
您还可以添加NSLog
语句,以便当任何人使用附加的XCode会话运行项目时,他们会看到类似于“请不要使用init
的控制台输出,请使用{ {1}}而是。“请注意,这是Apple本身历来采用不推荐的API调用的方法(以及在其文档中弃用的标记)。