我一直在复习关于继承的快速文档,有一件事我不太明白:似乎我可以在几乎任何Cocoa类上调用默认的无参数初始化器,尽管根据规则,我似乎不应该这样做。
例如,考虑NSNumber类,它直接从NSObject继承。NSObject定义了一个指定的初始化器:init()。NSNumber定义了一组指定的初始化器(如init(int value: Int32)等),但不覆盖init()。
根据这些文件,以下是规则:
假设为子类中引入的任何新属性提供默认值,则适用以下两条规则: 规则1:如果您的子类没有定义任何指定的初始化器,它会自动继承它的所有超类指定的初始化器。 规则2:如果您的子类提供其所有超类指定的初始化器的实现--或者根据规则1继承它们,或者提供自定义实现作为其定义的一部分--那么它会自动继承所有超类方便初始化器。 即使子类添加了更多方便的初始化器,也适用这些规则。
由于NSNumber确实定义了自己指定的初始化器,所以我希望根据Rule 1,NSNumber不会继承init()初始化器。但是init()包含在Xcode自动完成中,它不会导致编译器错误。
不同类的运行时行为似乎不同。当您调用该初始化程序时,NSNumber似乎崩溃了。NSInputStream (我第一次遇到这个问题)没有,但似乎没有正确地初始化子类实例变量。
看起来这应该是一个编译器错误。这只是斯威夫特的一个bug,还是我遗漏了什么?
发布于 2016-02-17 08:56:49
NSNumber和其他NS类不遵循Swift规则的原因是它们纯粹是在Objective中实现的。
取决于如何定义NSObject的子类,Swift如何与其交互。
最基本的子类将允许通过Swift调用init()和init(value: String):
@interface SomeClass : NSObject
@property (nonatomic, strong) NSString *value;
- (instancetype)initWithValue:(NSString *)value;
@end适当的子类实现将使其成为Swift只能调用init(value: String),如果调用init()将导致编译器错误:
@interface SomeClass : NSObject
@property (nonatomic, strong) NSString *value;
- (instancetype)initWithValue:(NSString *)value NS_DESIGNATED_INITIALIZER;
- (instancetype)init __attribute__((unavailable("init is unavailable")));
@end似乎NSNumber正在使用更接近第一种方法的东西
https://stackoverflow.com/questions/35447121
复制相似问题