Iphone 防止其他程序员调用init的最佳方法
在设计类层次结构时,有时子类添加了一个新的Iphone 防止其他程序员调用init的最佳方法,iphone,objective-c,cocoa-touch,init,Iphone,Objective C,Cocoa Touch,Init,在设计类层次结构时,有时子类添加了一个新的initWithSomeNewParam方法,最好禁用对继承自超类的旧init方法的调用 首先,我已经阅读了这个问题,其中建议的备选方案是重写init以在运行时抛出异常,或者重写并设置属性的默认值。在我的例子中,我不想提供默认值,我想明确指出不应该调用旧方法,而应该使用带有参数的新方法 所以运行时异常是可以的,但是除非对代码进行调试,否则团队中的其他程序员将无法注意到旧方法不再被使用 如果我是对的,就没有办法将方法标记为“private”。那么,除了添加
initWithSomeNewParam
方法,最好禁用对继承自超类的旧init
方法的调用
首先,我已经阅读了这个问题,其中建议的备选方案是重写init
以在运行时抛出异常,或者重写并设置属性的默认值。在我的例子中,我不想提供默认值,我想明确指出不应该调用旧方法,而应该使用带有参数的新方法
所以运行时异常是可以的,但是除非对代码进行调试,否则团队中的其他程序员将无法注意到旧方法不再被使用
如果我是对的,就没有办法将方法标记为“private”。那么,除了添加评论外,还有什么方法可以做到这一点吗
提前感谢。标记它已弃用?
开发者就是开发者,你不能阻止我们所有人
您可以在头文件中将
init
明确标记为不可用:
- (id) init __unavailable;
或:
使用后面的语法,您甚至可以给出原因:
- (id) init __attribute__((unavailable("Must use initWithFoo: instead.")));
如果有人试图调用它,编译器会发出一个错误(而不是警告)。initWith:Stuff和:OtherStuff永远不能超过方便的构造函数 在这方面,他们实际上应该
self = [self init];
if(self)
{
self.stuff = Stuff;
self.other = OtherStuff;
}
因此[object init]将始终返回预定义状态的对象,[object initWithStuff:stuff]将返回覆盖stuff的预定义状态的对象
基本上,我想说的是,不鼓励[object init]是一种不好的做法,特别是将来有人对您的子类进行子类化时……要添加@DarkDust发布的内容,您也可以使用
UNAVAILABLE\u ATTRIBUTE
- (id)init UNAVAILABLE_ATTRIBUTE;
当用户试图对此类的实例调用
init
时,这将引发错误。语法已缩短为:
- (instancetype)init NS_UNAVAILABLE;
注释和异常——您不能做太多其他事情。是的,但是编译器一点也不抱怨。我想用Xcode来突出显示亮红色XD的线条。我不同意。我认为海报想要的东西非常有意义(我也做过,尽管有运行时断言)。有时分配一个“空”对象是没有意义的,也不能给出默认值。特别是当实例被认为是不可变的或者是类集群的时候。是的,我知道这是一种不好的做法,但是对于某些类来说默认值没有意义。如果是这样的话,那么使用+(class)classWithPredefinedStuff:(Stuff*)Stuff;我同意托尼的观点,不管禁用它是否有用,这是一种不好的做法,应该避免@黑暗;你也可以初始化一个不可变数组。@不太可能。杰克:对,你得到了什么?空数组。但是,如果您想在其中包含内容,那么
init
对您不起作用。虽然数组为空可能有意义,但并非每个类都是如此。很好,我也不知道。这不会影响[MyClass new]
语法。这样的调用仍然使用init方法,没有任何错误或警告。@ Vineo Suliava:我认为使用<代码>新< /代码>是坏的风格,我知道没有人使用它。但是如果您这样做:只需在该类上用描述的属性标记new
。如果我们使用该属性,编译器将不允许我们在其自己的类方法中初始化该对象。这将在实现单例模式时引起问题。这个问题有解决方案吗?@Saifee:只需为单例模式的内部初始值设定项选择一个不同的名称,如initInternal
(顺便说一句,调用[super init]
仍然有效)。这是@DarkDust答案的一个简短而有用的形式,本质上是相同的:\define UNAVAILABLE\u ATTRIBUTE\u ATTRIBUTE__((不可用))
- (instancetype)init NS_UNAVAILABLE;