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;