一直喜歡使用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
的下劃線訪問實(shí)體變量. 也就是說你只能用self.xxx
這樣去訪問變量. 這樣下面的代碼在self.locationButton
就無限的自己調(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
去完成惰性初始化, 通過函數(shù)的返回值來確定初始化, 這樣你需要手動(dòng)寫一個(gè)func
去做, 個(gè)人不太喜歡這樣的方式, 不過也是一種實(shí)現(xiàn)方式.
lazy var players: [String] = self.initialPlayers()
func initialPlayers() -> [String] {
var players = ["John Doe"]
return players
}
最后補(bǔ)充一下, get和set的方法屬于計(jì)算屬性, 不能拿來作為惰性初始化.
Swift 編程語(yǔ)言中把這些理論統(tǒng)一用屬性來實(shí)現(xiàn)。Swift 中的屬性沒有對(duì)應(yīng)的實(shí)例變量,屬性的后端存儲(chǔ)也無法直接訪問。這就避免了不同場(chǎng)景下訪問方式的困擾,同時(shí)也將屬性的定義簡(jiǎn)化成一個(gè)語(yǔ)句。 一個(gè)類型中屬性的全部信息——包括命名、類型和內(nèi)存管理特征——都在唯一一個(gè)地方(類型定義中)定義。
Swift 屬性介紹