一直喜歡使用Objective C的惰性初始化, 這樣的代碼結(jié)構(gòu)會(huì)非常清晰和易維護(hù).
@property (nonatomic, strong) NSMutableArray *players;
- (NSMutableArray *)players {
if (!_players) {
_players = [[NSMutableArray alloc] init];
}
return _players;
}
當(dāng)你代碼里面調(diào)用NSArray *xx = self.players時(shí)候就會(huì)點(diǎn)用這個(gè)getter的方法.
使用Swift之后, 我第一個(gè)想法就是使用get 和 set 方法去實(shí)現(xiàn)惰性初始化, 想法很傻很天真. 下面的代碼肯定會(huì)Crash.
Swift不允許 Objective C的下劃線訪問(wèn)實(shí)體變量. 也就是說(shuō)你只能用self.xxx這樣去訪問(wèn)變量. 這樣下面的代碼在self.locationButton就無(wú)限的自己調(diào)用自己.
var locationButton: UIButton! {
get {
if self.locationButton == nil {
var button = UIButton()
return button
}
return self.locationButton
}
}
優(yōu)雅的實(shí)現(xiàn): 惰性初始化
實(shí)現(xiàn)方式:1
Swift提供了一個(gè)lazy的修飾詞, 使用格式 lazy var variable: Class = { //初始化方法 return }()這樣就會(huì)完成惰性初始化. 不需要再像Objective C一樣去判斷實(shí)體變量是否為nil.
lazy var mapView: MAMapView! = {
var mapView = MAMapView(frame: CGRectMake(0, 0, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame)))
mapView.delegate = self
mapView.compassOrigin.y = 24
mapView.scaleOrigin.y = 24
mapView.showsUserLocation = true
return mapView
}()
實(shí)現(xiàn)方式:2
使用func 去完成惰性初始化, 通過(guò)函數(shù)的返回值來(lái)確定初始化, 這樣你需要手動(dòng)寫(xiě)一個(gè)func去做, 個(gè)人不太喜歡這樣的方式, 不過(guò)也是一種實(shí)現(xiàn)方式.
lazy var players: [String] = self.initialPlayers()
func initialPlayers() -> [String] {
var players = ["John Doe"]
return players
}
最后補(bǔ)充一下, get和set的方法屬于計(jì)算屬性, 不能拿來(lái)作為惰性初始化.
Swift 編程語(yǔ)言中把這些理論統(tǒng)一用屬性來(lái)實(shí)現(xiàn)。Swift 中的屬性沒(méi)有對(duì)應(yīng)的實(shí)例變量,屬性的后端存儲(chǔ)也無(wú)法直接訪問(wèn)。這就避免了不同場(chǎng)景下訪問(wèn)方式的困擾,同時(shí)也將屬性的定義簡(jiǎn)化成一個(gè)語(yǔ)句。 一個(gè)類型中屬性的全部信息——包括命名、類型和內(nèi)存管理特征——都在唯一一個(gè)地方(類型定義中)定義。
Swift 屬性介紹