UIViewController
类定义了一个指定的初始化器,init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)
,而没有方便的初始化器,但是,可以编写以下代码并进行编译(Xcode 6.1.1)
let vc = UIViewController()
这怎麽可能?
根据Swift的书,下面是初始化继承的规则
如果您的子类没有定义任何指定的初始化器,则它会自动继承其所有超类指定的初始化器。 如果您的子类提供了其所有超类指定初始化器的实现--或者按照规则1继承它们,或者提供自定义实现作为其定义的一部分--那么它将自动继承所有超类方便初始化器。“ 摘录自:苹果公司。“斯威夫特编程语言”iBooks。https://itun.es/us/jEUH0.l
因此,UIViewController
不可能从它的祖先超类NSObject
继承init()
方法,那么初始化器从哪里来?
另外,由于每个快速类最终都必须调用其指定的初始化器,这不意味着initWithCoder:
也将调用init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)
吗?然而,在实践中,情况似乎并非如此。
发布于 2015-02-06 10:31:28
Swift书中的规则适用于Swift中定义的类。UIViewController
是从ObjC导入的类,因此它的行为受ObjC规则(或缺乏规则)的约束。
在ObjC中,指定的初始化器链接模式是您应该做的事情(与Swift中的编译器强制它是您唯一能做的事情不同)。如果您调用继承的初始化程序而不是指定的初始化程序,您将得到一个实例.但是,不能保证上述情况将处于合理的状态。(事实上,你几乎可以保证不会这样。)ObjC类的作者有时通过实现不应该调用的初始化器来进行防御性编码,并让它们抛出异常,但这里似乎并非如此。
这个特殊的案例可以说是某种类型的bug -- 向苹果公司提交一份文件并不是个坏主意。在从导入的ObjC API创建对象时,Swift应该强制执行初始化规则(在这种情况下,UIViewController
需要用NS_DESIGNATED_INITIALIZER
在ObjC中声明其指定的初始化器),或者应该实现UIViewController
以防止不正确的初始化。(尽管有可能,“修复”这两种方法都会产生兼容性副作用。)
发布于 2015-02-06 10:32:56
该init
函数上面的注释块包含以下文本:
/*
The designated initializer. If you subclass UIViewController, you must call the super implementation of this
method, even if you aren't using a NIB. (As a convenience, the default init method will do this for you,
and specify nil for both of this methods arguments.) ...
*/
据我理解,因为这是一个Objective类,所以允许它隐式继承方法。如果您快速创建该类的子类,您将无法访问super.init()
。如果您在Objective代码中创建您的子类而没有实现您自己的-[ init]
,那么您将能够使用()
构造您的子类。
因为您的项目与调用的类一起进入了Objective域,所以它能够找到选择器。一个目标-C类的快速子类只会遵循快速继承规则。
https://stackoverflow.com/questions/28371701
复制相似问题