首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当类不提供实现时,为什么可以调用init的无参数版本?

当类不提供实现时,为什么可以调用init的无参数版本?
EN

Stack Overflow用户
提问于 2016-02-17 03:06:11
回答 1查看 305关注 0票数 3

我一直在复习关于继承的快速文档,有一件事我不太明白:似乎我可以在几乎任何Cocoa类上调用默认的无参数初始化器,尽管根据规则,我似乎不应该这样做。

例如,考虑NSNumber类,它直接从NSObject继承。NSObject定义了一个指定的初始化器:init()NSNumber定义了一组指定的初始化器(如init(int value: Int32)等),但不覆盖init()

根据这些文件,以下是规则:

假设为子类中引入的任何新属性提供默认值,则适用以下两条规则: 规则1:如果您的子类没有定义任何指定的初始化器,它会自动继承它的所有超类指定的初始化器。 规则2:如果您的子类提供其所有超类指定的初始化器的实现--或者根据规则1继承它们,或者提供自定义实现作为其定义的一部分--那么它会自动继承所有超类方便初始化器。 即使子类添加了更多方便的初始化器,也适用这些规则。

由于NSNumber确实定义了自己指定的初始化器,所以我希望根据Rule 1,NSNumber不会继承init()初始化器。但是init()包含在Xcode自动完成中,它不会导致编译器错误。

不同类的运行时行为似乎不同。当您调用该初始化程序时,NSNumber似乎崩溃了。NSInputStream (我第一次遇到这个问题)没有,但似乎没有正确地初始化子类实例变量。

看起来这应该是一个编译器错误。这只是斯威夫特的一个bug,还是我遗漏了什么?

EN

回答 1

Stack Overflow用户

发布于 2016-02-17 08:56:49

NSNumber和其他NS类不遵循Swift规则的原因是它们纯粹是在Objective中实现的。

取决于如何定义NSObject的子类,Swift如何与其交互。

最基本的子类将允许通过Swift调用init()init(value: String)

代码语言:javascript
复制
@interface SomeClass : NSObject
@property (nonatomic, strong) NSString *value;
- (instancetype)initWithValue:(NSString *)value;
@end

适当的子类实现将使其成为Swift只能调用init(value: String),如果调用init()将导致编译器错误:

代码语言:javascript
复制
@interface SomeClass : NSObject
@property (nonatomic, strong) NSString *value;
- (instancetype)initWithValue:(NSString *)value NS_DESIGNATED_INITIALIZER;
- (instancetype)init __attribute__((unavailable("init is unavailable")));
@end

似乎NSNumber正在使用更接近第一种方法的东西

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35447121

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档