簡介
第一次接觸“正統”的swift項目,發現與之前的OC項目的結構有很大的改變,其中最大的的一點區別是在于在以前的MVC基礎之上又獨立出一層Manager,如題中所說的MVCM。對比以前的MVC架構,Manager層面主要抽離的是網絡訪問層面,即在Controller層不會再看早和網絡請求數據詳細相關的代碼,但是會在controller增加一個Manager類型的屬性,用以觸發請求,以及數據的使用。
代碼的結構及調用順序分析
Manager
- 代碼結構
下面是我自己總結的代碼的書寫順序,首先僅代表本人的書寫習慣,不一定代表廣泛性,另外,我是按照數據獲取流程標記的,僅作為思考的順序,真正的書寫的順序可以根據代碼的的美觀簡潔做具體調整- 繼承自網絡訪問工具類
- 定義數據請求函數
參數:不做詳述,根據具體需求填寫
網絡請求:
1.訪問網絡
2.網絡訪問成功對進行數據存儲(存儲到結構體)
3.回調:此層回調不是以前節結構中的數據網絡訪問成功時的回調,而是將Manager數據下載存儲完畢后對外界的通知,通知控制器可以進行使用數據 - 分頁相關的代碼(一句具體要需求增減)
不贅述 - 數據存儲容器聲明及初始化
在swift的數據一般存儲在結構體中,代替以前的模型類,一般通過json進行初始化, - 回調
閉包進行回調,作用參考2中解釋typealias dataManagerCallback = (type: HSDataManagerCallType, msg: String, isRefresh: Bool) -> Void
以下通過具體代碼進行演示
img M1
img M2
Controller
- 代碼結構
控制器中沒有了網絡訪問相關的代碼,取而代之的是要對Manager的聲明以及初始化,以及通過Manager進行網絡請求(在Manager中寫好函數,controller中Manager調用函數來觸發網絡請求)以及在回調中對數據進行獲?。ㄈ绻莟ableView 一般是進行刷新數據源操作)- 懶加載Manager,初始化
- 發起網絡請求
-
網絡回調
img C
Cell
-
代碼結構
關于cell的說一下幾點-
與tableView的分離
cell的創建依舊依賴于tableView,但是在cell的控件的賦值的過程移到cell內部,外部提供一個數據源的接口,在controller層面屏蔽cell內部細節,在cell中懶加載一個數據模型類型的屬性,在其didSet進對組件進行復制
img Ce1 - tableView 的行高的計算
在以前的計算行高,用frame 或者 自動布局和frame混合計算,前者對于動態的尺寸的計算,代碼量比較大,適合純代碼的開發,后者比前者的優勢在于很大部分的布局可以用自動布局實現,實現了大部分的自動化,但是對于行高計算cell行號,要綜合計算所有組件的行高的綜合,需要用frame進行計算。那么有沒有一種可以用自動布局全部搞定的方法,徹底實現自動化。
systemLayoutSizeFittingSize
img Ce2
簡單的翻譯下官方文檔:
標題是自動布局中的測量Parameters
指出滿足約束的最大的或者最小的可能的值
Fitting Size
此值是以上函數的參數的取值,是個枚舉量
img Ce3UILayoutFittingCompressedSize
使用最小的值作為選項
UILayoutFittingExpandedSize
使用最小的值作為選項
函數總結
對于button imageView label 等內部有內容的空間可以在固定寬度的情況下,通過systemLayoutSizeFittingSize函數進行壓縮(UILayoutFittingCompressedSize)或者(UILayoutFittingExpandedSize)來獲取高度值,且系統自動計算。
自定義cell類中添加的cell高度計算方法- tableView的優化
-
數據源方法的執行順序
(1)tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
(2)tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
代理方法的執行順序
(1)tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
執行N次,N為cell的個數
(2.1)tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
(2.2)tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) ===>引入此代理就是為了將cell的創建和灌入數據徹底分開,此方法用于灌值
2.1執行一次,2.2執行一次,然后2.1執行,這一套在estimatedHeight之后一對一的配套執行N次N為cell的個數
cell展示順序和數據的灌入(即行高的計算)的矛盾
在cell被灌入數據之前是不能得到精確的行高的,即2.2的執行需在2.1,但是與系統的調用順序相違背。
解決方案
系統的調用順序是無法更改的,所以考慮在展示之前先將cell的高度進行計算,然后緩存。高度的計算,依據上文總結只要有了數據即可計算行高,但是前提此方法要依賴cell去執行,故考慮在數據源中增加一個屬性,計算每個cell的高度,由于需要對數據進行緩存,故此屬性進行懶加載