加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ios – 如何使用NS_DESIGNATED_INITIALIZER并覆盖init?

发布时间:2020-12-14 17:59:37 所属栏目:百科 来源:网络整理
导读:好吧,这无疑是一个最佳实践问题,但我想要做对,所以希望有人可以启发我: 场景非常标准,但有一个转折点: 我在我编写的框架中有一个类,它直接从NSObject继承.它有一个指定的初始化程序,有很多参数,其中大多数都是非空的.由于该东西是框架的一部分,我明确使用N
好吧,这无疑是一个最佳实践问题,但我想要做对,所以希望有人可以启发我:

场景非常标准,但有一个转折点:
我在我编写的框架中有一个类,它直接从NSObject继承.它有一个指定的初始化程序,有很多参数,其中大多数都是非空的.由于该东西是框架的一部分,我明确使用NS_DESIGNATED_INITIALIZER宏(我并不总是在较小的个人应用程序中使用).
问题是这导致XCode警告我也覆盖init,即超类的指定初始化程序.但另外它要求我从它调用我指定的initalizer,这是我不能做的,因为我的参数缺乏有意义的默认值.
我真的不想在“小”init中抛出异常,我更愿意返回nil.

为了摆脱警告,我在我的班级扩展中添加了init作为第二个指定的initalizer,如下所示:

@interface MyClassName ()
// some other stuff not relevant`

-(nullable instancetype)init NS_DESIGNATED_INITIALIZER;

@end

现在我可以安全地返回零;在我想要的覆盖init方法中.
这意味着我的文档(我正在使用appledoc)和扩展XCode的代码完成不会告诉使用我的框架的人,init实际上也是一个指定的初始化程序(因此他们不会意外地使用它),但它仍然存在(例如,在单元测试中,这可能会派上用场).

我的问题是:除了实际在生产中使用它的人之外,还有任何危险吗,之后快乐地发送消息给nil而没有意识到?这是少数几个在init中抛出异常的情况之一吗?

解决方法

而不是仅仅从init返回nil(并且可能添加评论说你不应该调用它) – 你应该将它标记为不可用.

这不仅会消除关于你没有覆盖NSObject的指定初始化程序的警告 – 如果有人试图调用init而不是指定的初始化程序,它也会产生编译时错误.

为此,您可以使用NS_UNAVAILABLE宏,也可以使用不可用的__attribute__,如this answer所示.使用__attribute__的优点是您可以指定编译器将向用户显示的消息.

例如:

@interface Foo : NSObject

-(instancetype) init __attribute__((unavailable("You cannot create a foo instance through init - please use initWithBar:")));

-(instancetype) initWithBar:(Bar*)bar NS_DESIGNATED_INITIALIZER;

@end

...


Foo* fooA = [[Foo alloc] init]; // ERROR: 'init' is unavailable: You cannot create a foo instance through init - please use initWithBar:

Foo* fooB = [[Foo alloc] initWithBar:[[Bar alloc] init]]; // No error

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读