2016-08-13 92 views
1

在如下因素例如:UIView.init()記錄在哪裏?

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 documentation,只有一個init(frame :)(和(init:coder))。

根據documenation爲NSObject。 init()

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

所以必須有一個UIView.init()重寫NSObject.init()並依次調用init(frame:)。但這UIView.init()沒有記錄?或者我錯過了這個文檔?

回答

0

如果你在swift中調用MyView()。這意味着它調用默認構造函數,即調用init。如果你想在目標c中調用initWithFrame,那麼你必須調用像MyView這樣的構造函數(frame:CGRect)。而對於細節你必須遵循蘋果文檔。

+0

謝謝,但這不是我問。 – Peter

+0

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html。 –

1

我找不到UIView.init的文檔,但確實存在UIView.init。如果您在print ("...init with frame")處設置了斷點,您將在調試導航器中看到[UIView init]的調用。彙編代碼清楚地表明它使用CGRectZero作爲框架調用objc_msgSendinitWithFrame:

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 
+0

謝謝。這也是它對我的看法。這似乎只是缺少文檔,然後我想。對於iOS中最常見的類之一的初始化程序奇怪的是沒有記錄! – Peter

+0

我懷疑蘋果真的想鼓勵使用其他初始化程序。如果您只是使用「MyView(frame:CGRectZero)」,調用樹會更短。 – vacawama

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並執行它們自己的初始化。在這裏你看到「custom」和「you」的地方,把它看作是一個子類的實現者 - 也就是說,這裏的「你」同樣適用於你,在你的應用中創建新類的第三方開發者,以及其他蘋果類的作者,其子類NSObject。 (你知道的,只是他們的所有。)


蘋果的API文檔似乎工作,他們只在對方法的方法級別由一個類中聲明擁有文檔的方式 - 有麥凱納t關於UIView的所有數據都從它的所有超類繼承而來,也沒有在它們從UIView繼承的所有方法的許多UIView子類中使用。

如所指出的在其他的答案時,無參數的初始值設定爲UIView相當於使用init(frame:)和傳球CGRect.zero。儘管Apple的文檔沒有地方描述UIView.init(),但它們可能會有助於他們討論其他地方的繼承初始化器的影響。 (也許在UIView class overview?)這可能是值得filing another documentation bug.

+0

感謝您的回覆。 然而,您的帖子中唯一直接解決我的問題的部分是: 「Apple的API文檔似乎可以在UIView中運行..inherit的方式。」 這的確是蘋果文檔的工作原理嗎?如果是這樣,那麼它不應該(imo)。我提出了一個關於此的錯誤 - 感謝您的建議。所有可以在對象上調用的重載方法(公共地)都應該被記錄下來。如果沒有arg UiView.init()現在(似乎)做的事情可能會在沒有通知的情況下發生變化,如果沒有至少清楚地記錄,破壞現有代碼。 – Peter

+0

@rickster UIView如何從NSObject繼承初始值設定項?由於UIView定義了自己指定的初始值設定項,所以初始值設定項繼承被阻止,是嗎? – Verticon

+0

@RobertVaessen Initializers是方法,所以子類總是繼承它們,就像它們做其他方法或屬性一樣。子類可以改變哪些初始化器被指定爲初始化器,但是這並不妨礙其他初始化器被繼承。 – rickster