(一)可選項:java
(二)懶加載:ios
在OC開發中,懶加載通常自定義控件。在Swift中,懶加載仍是須要用的,能夠保證控件延遲建立,還能避免處理控件解包。若是直接定義控件var label = UILabel,根據代碼從上到下,會讓控件在ViewDidLad以前就提早建立了。因此須要懶加載。OC中懶加載就是Get方法,Swift直接lazy var。固然也能夠private lazy var來限定做用域。swift
(1)簡單的懶加載:閉包
(2)完整的懶加載:()就是函數執行,就是一個特殊的閉包,因此懶加載本質是一個閉包。通常不這麼寫。app
(3)OC和Swift區別框架
*OC:ide
OC是等於nil時候就懶加載函數
當label設nil的時候就在此調用。在ios6中,didReceiveMemoryWarning是不清理視圖的。spa
此時釋放的時候就會報錯。由於定義的時候沒有?,就是必定有值得。3d
那麼若是定義時候加? 一旦label = nil,也不會在執行懶加載了!由於懶加載根本沒寫若是是空就建立。
懶加載只會在第一次調用的時候執行閉包。Swift中必定注意不要主動清理視圖或控件,由於懶加載不會建立了(例如內存警告別幹掉控件,幹掉了在也用不成了,由於懶加載就一次)
(三)計算型屬性(只讀):
(1)getter/setter(開發不用):
// 開發通常不用,還給搞一個_name。 // swift通常不會重寫getter和setter private var _name: String? // 僞裝的一個值 var name: String? { get{return _name} set{_name = newValue}} // get返回成員變量 set記錄成員變量 override func viewDidLoad() { super.viewDidLoad() demo() }
(2)計算型屬性:readOnly只讀:OC中重寫get。Swift也是重寫get,無論set就能夠。
// 只讀,此時set賦值時候就會報錯 var name: String? { get{return "ABC"}} 還有一種簡寫: var name: String? { return "ABC"}
看這類屬性,是自己不保存內容的,都是經過計算得到結果。就能夠當我就是個沒有參數只有返回值的函數!!我每次return值給你個人任務就完成了。每次你調用我這個屬性的時候,我都會進行一次計算!都會執行個人代碼而後return給你。我自身不存儲的。
(3)懶加載和計算型屬性的區別:
(4)存儲型屬性:須要開闢空間,存儲數據。通常的屬性都是存儲型屬性(懶加載)
(5)存儲和計算均可以?或者不加。看狀況是否是必選
(四)Swift中設置模型數據:
Swift作好模型後。別的控件拿到模型後,由視圖本身來顯示。此時在didSet裏寫。就是替代OC的Setter方法。(OC的Setter要考慮_成員變量 = 值,並且若是是copy須要.copy,而Swift不須要考慮一切)
(五)命名空間和反射機制
(1)命名空間:
*在同一個空間(項目),全局共享。用第三方時,若是直接拖拽,那就從屬於一個空間,頗有可能衝突,因此用Cocopod
*動態得到命名空間(從info.plist加載),命名空間和項目名稱有關係。info的Bundle name其實就是命名空間(通常寫的很奇怪 #(ProdectNmae))。
打印info
print(Bundle.main.infoDictionary)
賦值
// 獲取命名空間的值,可選 let str = Bundle.main.infoDictionary?["CFBundleName"] as? String ?? "" let con = NSClassFromString(str + "." + "ViewController") as? UIViewController.Type
(2)反射機制:對於任何類均可以知道類的全部屬性和方法,對於任何對象均可以調用任何屬性和方法,這種動態獲取的信息和動態調用對象屬性方法的功能成java的反射機制(Swift也有了)
*在OC中利用反射機制
*在Swift中利用反射機制相似。工做中用的不少不少。
場景:AppDelegate(OC中也用過,利用NSClassFromString得到類,而後設置根控制器。可是Swift中多了一個命名空間寫法。)
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { window = UIWindow(frame: UIScreen.main.bounds) // 依據String名字拿到控制器(添加項目名稱,命名空間,不能有數字和特殊符號) // 返回的是AnyClass? 須要as?強轉 // 控制器添加Type類型 let rootControl = NSClassFromString("SwiftyDemo.ViewController") as? UIViewController.Type let vc = rootControl?.init() window?.rootViewController = vc window?.makeKeyAndVisible() return true }
第三方框架,用了不少反射機制和工廠方法,爲了實現大量的解耦和封裝,很麻煩。一個方法可能跳10個方法10個控制器才寫了一個加法。可是若是涉及高級開發和封裝,必需要通過這一步。