Objective c 重新定义父类声明为NS_不可用的初始化器
我想重新定义一个初始化器,它以前被父类声明为Objective c 重新定义父类声明为NS_不可用的初始化器,objective-c,initialization,Objective C,Initialization,我想重新定义一个初始化器,它以前被父类声明为NS\u UNAVAILABLE 例如: @interface Parent : NSObject // Unavailable - (instancetype)init NS_UNAVAILABLE; // Some other (appropriate) initialiser - (instancetype)initWithWhatever:(id)whatever NS_DESIGNATED_INITIALIZER; @end 对子初始
NS\u UNAVAILABLE
例如:
@interface Parent : NSObject
// Unavailable
- (instancetype)init NS_UNAVAILABLE;
// Some other (appropriate) initialiser
- (instancetype)initWithWhatever:(id)whatever NS_DESIGNATED_INITIALIZER;
@end
对子初始化器的任何调用都需要传播到父级指定的初始化器,这是有意义的
假设默认参数在子类上有意义,因此:
@interface Child : Parent
// Propagates to initWithWhatever:
- (instancetype)init NS_DESIGNATED_INITIALIZER;
@end
尽管初始化器由子类Xcode重新声明,但似乎仍然认为它不可用。有办法解决这个问题吗?看起来这种行为在Xcode 8中得到了修复(在8.1中进行了测试) 我还有一些注意事项:
子项
实现完全完成,您应使用任何覆盖init或使其不可用。因为Child
当然会从Parent
继承这个初始值设定项
init
不可用,那么也可以使new
不可用所以。从现在起,我们可以借助
NS\u指定的初始化器
和NS\u不可用
组合,在Objective-C中完全控制我们的初始化器。与Swift相比,它需要更多的工作,但我认为这是值得的。特别是如果你想让你的类更好地与Swift兼容的话。要感谢那些家伙,他们认为现在的静态类型编程语言是个好主意,破坏了Objective-C。Objective-C既不需要这样的装饰,也不符合Objective-C的基本思想。但是,你需要一个解决方案。由于对象初始化没有什么特别之处,特别是初始化方法没有什么特别之处,只需更改方法的名称即可。这不是你的解决方案吗?在子类中再次使用方法会导致Liskov出现问题。我知道它不符合Objc的初始化器概念,但一些基类对某些初始化器不再有意义(即,没有默认值,但需要额外的参数)这一事实使我经常解决这些问题。Objective-c的设计师们弄错了,我想我可以用一个不同的名字,但是什么initWithNothing
?在几层继承之后,这将走向何方?我同意,Objective-C asNS\u UNAVAILABLE
的最新变化指向了错误的方向,但至少它使声明在Liskov的意义上变得更好。然而,显然,-initWithDefaults
将是一个合适的名称。由于不需要正式为您添加NS\u UNAVAILABLE
,因此您仍然使用-initWithDefaults
,直到您想使用NS\u UNAVAILABLE
。你说的是一个容易解决的问题。(顺便说一句:在许多编程语言中,它类似于final
。)这根本不是我的意思,而是构造函数继承的整个概念是错误的。不应该继承构造函数。这一事实并没有损害Leskov的替换原则,因为只有在构造对象之后才适用(也许使用反射实例化是另一个问题,但我认为也不应该使用反射)。我不明白,它与final
有什么相似之处?这个概念并没有错,与堆栈分配语言相比,它工作得更好。它类似于final
,因为基类决策是继承的,没有机会在子类中更改它。