我開始用Markdown方式來記筆記了』栈澹現(xiàn)在第十一講的視頻都已經(jīng)放出來了。為了提速吵血,內(nèi)容會記得比較簡單谎替,以記錄核心內(nèi)容為主,后面再逐步進行補充蹋辅。對本講有任何疑問钱贯,請留言,我會優(yōu)先進行更新侦另。
<h4>本講簡介:</h4> 本講通過演示來介紹秩命,最后幾分鐘時間介紹了內(nèi)存管理,主要是對引用類型對象的管理褒傅。
演示:
為FaceIt增加 Master-Detail View
Navigation View
View Controller 的生命周期
Instantiated
awakeFromNib
segue preparation happens
outlets get set
viewDidLoad
viewWillAppear
viewWillLayoutSubviews
viewDidLayoutSubviews
viewWillDisappear
內(nèi)存管理
簡單來講弃锐,內(nèi)存管理是自動的或?qū)﹂_發(fā)者透明的。
ARC vs MRC vs GC
自動引用計數(shù)
手動引用計數(shù)
垃圾回收技術(shù)
Strong Weak unOwned
閉包 (Closures)
Closures: 一等公民殿托,是引用類型霹菊,居住在堆上
<pre>addUnaryOperation("?", operation: { (x: Double) -> Double in
display.textColor = UIColor.green
return sqrt(x)
} )</pre>
<pre>addUnaryOperation("?") {
self.display.textColor = UIColor.green
return sqrt($0)
} </pre>
<pre>addUnaryOperation("?") { [ unowned me = self ] in
me.display.textColor = UIColor.green
return sqrt($0)
} </pre>
這個例子有幾個知識點:
1,閉包做為最后一個參數(shù)的簡化寫法
2碌尔,介紹了一種可能產(chǎn)生內(nèi)存引用互鎖的情況
3浇辜,引入一個unowned 變量 打破循環(huán)
更容易想到的打破循環(huán)引用的
<pre>addUnaryOperation("?") { [ weak weakSelf = self ] in
weakSelf?.display.textColor = UIColor.green
return sqrt($0)
} </pre>
但還可以這樣寫
<pre>
addUnaryOperation("?") { [ weak self ] in
self?.display.textColor = UIColor.green
return sqrt($0)
}
</pre>
第十三講結(jié)尾介紹了一個需要避免memory cycle 的情況
@escaping 用于修飾閉包。閉包默認(rèn)是非逃逸的唾戚。@escaping修飾表示逃逸柳洋,即閉包的執(zhí)行會產(chǎn)生對閉包外部的訪問,或某種形式上的副效果叹坦。在Swift 3以前熊镣,閉包默認(rèn)是逃逸的, 非逃逸閉包要用@noescaping修飾。
<h4>再談绪囱!</h4>
上一講里面提到過测蹲,因為在聲明faceView時使用了!鬼吵,在使用它時是不需要加扣甲?的。但在本講中齿椅,如果在下面訪問faceView時不加琉挖?,應(yīng)用會出錯涣脚。
<pre>
//FaceViewController.swift
@IBOutlet weak var faceView: FaceView!
private func updateUI() {
switch expression.eyes {
case .open:
faceView?.eyesOpen = true
case .closed:
faceView?.eyesOpen = false
case .squinting:
faceView?.eyesOpen = false
}
faceView?.mouthCurvature = mouthCurvature[expression.mouth] ?? 0.0
}</ol>
</pre>
原因在于示辈,Segue總會建立新的MVC實例。而在 prepare(for segue) 中<code> faceViewController.expression = expression </code>引發(fā)了對上面的updateUI()的調(diào)用遣蚀,而此時faceView還沒有被建立矾麻,仍然為nil。所以需要加芭梯?险耀。這說明使用!后粥帚,只是對編譯器來說可以接受沒有unwrapping胰耗。但像本例的情況仍然需要。
<pre>
<ol> //EmotionsViewController.swift
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destinationViewController = segue.destination
if let faceViewController = destinationViewController as? FaceViewController,
let identifier = segue.identifier,
let expression = emotionalFaces[identifier] {
faceViewController.expression = expression
}
}<ol>
</pre>
<h4>課后練習(xí)</h4>
<p>在增加了navigation Controller 后芒涡,應(yīng)用啟動后直接顯示了 Face View柴灯。老師留了一個練習(xí),是希望啟動后顯示帶有三個按鈕的emotion 選擇頁面费尽。老師還給了個提示赠群,要用到后面講的delegate的內(nèi)容。在這兒我們自己實現(xiàn)一下旱幼。</p>
<ol><li>打開幫助文檔查描,在輸入框敲入 Navig,這時提示列表就回顯示出一些推薦的結(jié)果柏卤,選取 navigationController(_:willShow:animated:)
<li>根據(jù)幫助內(nèi)容我們確定這個方法會在每一頁顯示前被調(diào)用冬三。而且從幫助頁面的頂部我們可以知道這個方法屬于協(xié)議 UINavigationControllerDelegate
<li>創(chuàng)建一個新的 Cocoa Touch Class 文件,將其命名為EmotionsNavViewController缘缚,父類先不用動勾笆,后面再改。
<li>打開Main.storyboard桥滨, 選中Navigation Controller 查看 identity inspector 中的 class 為 UINavigationController窝爪。因而我們打開新建的文件弛车,將
<pre><code>class EmotionsNavViewController: ... { </code></pre> 替換為
<pre><code>class EmotionsNavViewController: UINavigationController, UINavigationControllerDelegate {</code></pre>回到 identity inspector 中將Navigation Controller 的 class 的值改為 EmotionsNavViewController
<li>在類中添加我們在第1步找到的方法
<pre> func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
}</pre><li>在這兒我們該怎么做呢?查看UINavigationController的幫助
“A navigation controller coordinates its behavior with its delegate object. The delegate object can override the pushing or popping of a view controller ... "
我們看到了 override蒲每,所以有戲纷跛。我們在willShow 方法中加入
<pre><code>popViewController(animated: true)</code></pre>運行一下,沒有效果邀杏。在新加的代碼上設(shè)一個斷點贫奠,會發(fā)現(xiàn)根本沒有被調(diào)用。
<li>在viewDidLoad()里面加入
<pre><code>delegate = self</code></pre>再次執(zhí)行程序淮阐,成功地顯示了我們想要的頁面叮阅。
<li>點一下 sad 按鈕刁品,oops泣特! FaceView 出現(xiàn)后又收回了√羲妫看來willShow中的代碼還在起作用状您。增加一個屬性
<pre>private var displayed = false</pre>然后將 willShow的內(nèi)容改為
<pre>if displayed == false {
displayed = true
popViewController(animated: true)
}</pre> command+R 運行程序。一切OK兜挨。</ol>
官方答案在第八講膏孟。