一直喜欢使用Objective C
的惰性初始化, 这样的代码结构会非常清晰和易维护.
@property (nonatomic, strong) NSMutableArray *players;
- (NSMutableArray *)players {
if (!_players) {
_players = [[NSMutableArray alloc] init];
}
return _players;
}
当你代码里面调用NSArray *xx = self.players
时候就会点用这个getter的方法.
使用Swift
之后, 我第一个想法就是使用get 和 set 方法去实现惰性初始化, 想法很傻很天真. 下面的代码肯定会Crash.
Swift
不允许 Objective C
的下划线访问实体变量. 也就是说你只能用self.xxx
这样去访问变量. 这样下面的代码在self.locationButton
就无限的自己调用自己.
var locationButton: UIButton! {
get {
if self.locationButton == nil {
var button = UIButton()
return button
}
return self.locationButton
}
}
优雅的实现: 惰性初始化
实现方式:1
Swift
提供了一个lazy
的修饰词, 使用格式 lazy var variable: Class = { //初始化方法 return }()
这样就会完成惰性初始化. 不需要再像Objective C
一样去判断实体变量是否为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
}()
实现方式:2
使用func
去完成惰性初始化, 通过函数的返回值来确定初始化, 这样你需要手动写一个func
去做, 个人不太喜欢这样的方式, 不过也是一种实现方式.
lazy var players: [String] = self.initialPlayers()
func initialPlayers() -> [String] {
var players = ["John Doe"]
return players
}
最后补充一下, get和set的方法属于计算属性, 不能拿来作为惰性初始化.
Swift 编程语言中把这些理论统一用属性来实现。Swift 中的属性没有对应的实例变量,属性的后端存储也无法直接访问。这就避免了不同场景下访问方式的困扰,同时也将属性的定义简化成一个语句。 一个类型中属性的全部信息——包括命名、类型和内存管理特征——都在唯一一个地方(类型定义中)定义。
Swift 属性介绍