UIView.init()在哪里记录?

时间:2016-08-13 08:13:22

标签: ios swift

在下面的例子中:

[dateformat setDateFormat:@"yyyy-MM-dd"]; //Whatever you want to change the date format change here
NSString *strDateValue = [dateformater stringFromDate:dateValue]; 

.......

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()。 但是根据UIView documentation,只有一个init(frame :)(和(init:coder))。

根据NSObject的documenation。 init()

  

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

因此必须有init(frame: CGRect)覆盖UIView.init(),然后调用NSObject.init()。但是这个init(frame:)没有记录?或者我错过了这个文档?

3 个答案:

答案 0 :(得分:1)

我找不到UIView.init的文档,但UIView.init确实存在。如果您在print ("...init with frame")设置断点,则会在 Debug Navigator 中看到对[UIView init]的调用。汇编代码清楚地显示它使用objc_msgSend作为框架调用initWithFrame: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   

答案 1 :(得分:1)

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

在Swift和ObjC-bridged-to-Swift中,类都必须将从超类继承的方法/属性声明为公共API,或者通过符合协议来包含。继承或协议采用意味着该类支持这些方法/属性,但它并没有告诉您类的实现所做的事情。为此,你必须仔细阅读文档。

在您引用的NSObject.init() doc上展开一点(对某些重点进行了编辑):

  

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

     

init()类 中定义的NSObject方法 没有初始化...(1)

     

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

这可能更清楚(I recommend filing a bug against the documentation so Apple knows to improve it),所以快速翻译:

  1. 在“裸”NSObject实例中,init()什么都不做。也就是说,该方法纯粹用于子类化。

  2. 应该调用子类super并执行自己的初始化。你在这里看到“自定义”和“你”的地方,把它作为子类的实现者来读 - 也就是说,“你”这里同样适用于你,第三方开发者在你的应用程序中创建新类,以及子类NSObject的其他Apple类的作者。 (你知道,几乎所有这些。)

  3. Apple的API文档似乎有用,他们只在方法级别为类声明的方法提供了文档 - UIView上没有文档可用于它继承的所有数百种方法它的所有超类,以及它们从UIView继承的所有方法的许多UIView子类中的每一个。

    如其他答案中所述,UIView的no-args初始值设定项等同于使用init(frame:)并传递CGRect.zero。尽管Apple的文档没有地方可以将描述附加到UIView.init(),但它们可能有助于他们在其他地方讨论继承的初始化者的影响。 (也许在UIView class overview?)这可能值filing another documentation bug.

答案 2 :(得分:0)

如果你在swift中调用MyView()。这意味着它调用默认构造函数,即调用init。如果你想在目标c中调用initWithFrame,那么你必须调用像MyView(frame:CGRect)这样的构造函数。详情请参阅Apple文档。