0
我將一些代碼從Objc移植到Swift。並在Swift的初始化生命週期中掙扎。從簡化的角度來看,我試圖在這裏使用4名玩家:Swift View和控制器共享變量初始化問題
- 一個叫做
Program
的對象。這是我目前主要的頂級模型對象。剩下的3名球員都希望獲得他的一個實例。 - A
ProgramEditController
,畫在我的Main.storyboard。他負責實例化初始程序,這不能直接作爲屬性初始化程序完成。 - 頂級自定義UIView子類,名爲
ProgramTimelineView
。在Main.storyboard中繪製,管理各種專業子視圖。鏈接到我的ViewController的屬性。還有它的子視圖的屬性。它希望訪問該程序,因此它可以進行佈局並將其傳遞給子視圖。 ProgramTimelineView
的特定子視圖ProgramGridView
。這些不在XCode畫布工具中繪製,而是直接由包含ProgramTimelineView
的實例化。它想要訪問本程序。用它來做他的自定義drawRect
。
下面是我的控制器相關代碼:
class ProgramEditController: UIViewController {
// MARK: - Variables
@IBOutlet var timelineView:ProgramTimelinesView!
var site = Site()
var program:Program!
// MARK: - Initialize
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
// set up the new program
self.program = self.site.newProgram()
// get it into our top view before it starts drawing
self.timelineView.program = self.program
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder) // Why does Swift make me have a redundant thing here?
}
}
而對於ProgramTimelinesView:
class ProgramTimelinesView: UIView {
// MARK: - Variables
var gridView = ProgramGridView()
var program:Program! {
didSet {
self.gridView.program = self.program
}
}
// MARK: - Initialization
func addGridView() {
self.gridView.alpha = 0.0
self.gridView.opaque = false
self.addSubview(self.gridView)
}
func commonInit() {
self.addGridView()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.commonInit()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.commonInit()
}
}
最後爲ProgramGridView
:
class ProgramGridView: TimeAxisView {
// MARK: - Variables
var program:Program!
override func drawRect(rect: CGRect) {
// access self.program in here
}
}
我想過會發生:
ProgramEditController.init(nibName...)
會先着火。- 超級通話會導致我的
ProgramTimelineView.init(coder)
觸發。 - ProgramTimelineView實例將首先調用初始化
gridView
其設置爲一個新的ProgramGridView
視圖 - 的的
ProgramTimelineView.init(coder)
其餘部分將運行,這將增加在GridView到視圖樹。 - 控件將返回到
ProgramEditController.init(nibName)
初始值設定項。控制器的program
屬性將被填充。 - 裝訂
timelineView
將有其program
屬性集。 ProgramTimelineView
將依次設置gridView
的program
屬性。
儘管在步驟4和5之間似乎發生了什麼,但發生了drawRect()
。這會導致seg錯誤,因爲gridView的程序尚未設置!但是爲什麼現在要發佈drawRect()呢?我認爲在所有的初始化者都解僱之前這種情況不會發生。但顯然有一些副作用正在發生。用什麼正確的模式/成語來避免這種情況?我真的不想把所有的program!
都變成program?
,然後把每個地方都放進去/守衛。