阻止其他程序员调用-init的最佳方法

时间:2012-03-09 12:44:22

标签: iphone objective-c cocoa-touch init

在设计类层次结构时,有时子类添加了一个新的initWithSomeNewParam方法,并且希望禁用对从超类继承的旧init方法的调用。

首先,我已经阅读了问题here,其中建议的替代方法是覆盖init以在运行时抛出异常,或覆盖并设置属性的默认值。在我的情况下,我不想提供默认值,我想清楚地表明不应该调用旧方法,而是应该使用带参数的新方法。

因此运行时异常很好,但除非调试代码,否则团队中的其他程序员无法注意到旧方法不再用于使用。

如果我没错,就无法将方法标记为“私有”。所以,除了添加评论之外,有没有办法做到这一点?

提前致谢。

6 个答案:

答案 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)

标记它已被弃用? 开发人员将是开发人员,你无法阻止我们所有人! ; - )

How do I flag a method as deprecated in Objective-C 2.0?

答案 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调用的方法(以及在其文档中弃用的标记)。