UIView.init()在哪里被logging?

在下面的例子中:

import UIKit class MyView: UIView { override init(frame: CGRect) { super.init(frame: frame) print ("...init with frame") } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) print("...init with coder") } } 

…….

  let var = MyView() // "...init with frame" gets printed 

所以看来MyView()调用UIView.init() ,然后调用init(frame: CGRect) 。 但是根据UIView文档 ,只有一个init(frame :)(和(init:coder))。

根据NSObject的文档 。 在里面()

没有初始化; 它只是返回自我。

所以必须有一个覆盖NSObject.init()UIView.init() ,然后调用init(frame:) 。 但是这个UIView.init()没有logging? 还是我错过了这个文档?

我没有findUIView.init文档,但是UIView.init确实存在。 如果您在print ("...init with frame")设置了断点print ("...init with frame") ,您将在Debug Navigator中看到对[UIView init]的调用。 汇编代码清楚地显示调用objc_msgSendinitWithFrame:使用CGRectZero作为框架:

 UIKit`-[UIView init]: 0x10b3ba160 <+0>: pushq %rbp 0x10b3ba161 <+1>: movq %rsp, %rbp 0x10b3ba164 <+4>: subq $0x20, %rsp 0x10b3ba168 <+8>: movq 0xc52f71(%rip), %rsi ; "initWithFrame:" 0x10b3ba16f <+15>: movq 0xcd5f72(%rip), %rax ; (void *)0x000000010f732690: CGRectZero 0x10b3ba176 <+22>: movq 0x18(%rax), %rcx 0x10b3ba17a <+26>: movq %rcx, 0x18(%rsp) 0x10b3ba17f <+31>: movq 0x10(%rax), %rcx 0x10b3ba183 <+35>: movq %rcx, 0x10(%rsp) 0x10b3ba188 <+40>: movq (%rax), %rcx 0x10b3ba18b <+43>: movq 0x8(%rax), %rax 0x10b3ba18f <+47>: movq %rax, 0x8(%rsp) 0x10b3ba194 <+52>: movq %rcx, (%rsp) 0x10b3ba198 <+56>: callq *0xcd7042(%rip) ; (void *)0x000000010c8b9800: objc_msgSend 0x10b3ba19e <+62>: addq $0x20, %rsp 0x10b3ba1a2 <+66>: popq %rbp 0x10b3ba1a3 <+67>: retq 

UIView.init()存在 – 但是,它没有公开声明,因为该声明是从NSObject类inheritance的。

在Swift和ObjC-bridged-to-Swift中,一个类都不得不声明它从一个超类inheritance的方法/属性,或者通过符合一个协议来包含它。 inheritance或协议采用意味着类支持这些方法/属性,但是它不会告诉你什么类的实现。 为此你必须仔细阅读文件。

在你引用的NSObject.init() 文档上进行一些扩展(带有一些重点的编辑):

由子类实现以便在分配内存后立即初始化一个新的对象(接收者)。

NSObject定义init()方法没有初始化…(1)

在这个方法的自定义实现中,你必须调用super的初始化程序,然后初始化并返回新的对象…(2)

这可能会更清楚( 我build议提交一个对文档的错误,所以苹果知道改善它 ),所以快速翻译:

  1. 在一个“裸”的NSObject实例中, init()什么都不做。 也就是说,这个方法纯粹是为了子类化。

  2. 预计子类会调用super并执行自己的初始化。 在这里你看到“custom”和“you”的地方,把它看作是一个子类的实现者 – 也就是说,这里的“你”同样适用于你,在你的应用中创build新类的第三方开发者,其他Apple类的作者, NSObject子类。 (你知道,几乎所有这些。)


苹果的API文档似乎工作的方式,他们只有方法级别的文档方法声明的类 – 没有关于UIView的所有数百种方法,它从所有的超类inheritance的文档,也没有从UIViewinheritance的所有方法的每个UIView子类。

正如其他答案所述, UIView的no-args初始值设定项相当于使用init(frame:)并传递CGRect.zero 。 尽pipe苹果公司的文档没有把描述附加到UIView.init() ,但是他们可能会在其他地方讨论inheritance的初始化器的效果。 (也许在UIView类概述 ?)这可能是值得提交另一个文档错误。

如果你在swift中调用MyView()。 这意味着它调用默认的构造函数即init被调用。 如果你想在目标c中调用initWithFrame,那么你必须调用像MyView(frame:CGRect)这样的构造函数。 而对于细节你必须遵循苹果文档。