懒加载可以让你不用关心变量的创建时机,等到真正使用的时候才去创建并且能保证在使用的时候已经初始化完毕,在一定程度上可以提高性能。
OC懒加载的原理:
重写变量的 getter 方法,在getter方法里判断变量 if 变量 == nil 则初始化变量 ,否则直接返回已经初始化完毕的变量,所以我们在调用懒加载的变量时 一定要使用 self.变量名(通过getter方法取值)。
话不多说先看一段OC懒加载实现:
- (UICollectionViewFlowLayout *)flowLayout {
if (!_flowLayout) {
_flowLayout = [[UICollectionViewFlowLayout alloc] init];
_flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
_flowLayout.minimumInteritemSpacing = 0;
_flowLayout.minimumLineSpacing = 0;
}
return _flowLayout;
}
我们在调用 self.flowLayout 的时候其实就是在调用变量的 getter 方法。
再看swift 中的懒加载实现:
lazy var dataSource = Array<String>()
简单暴力一行代码就可以实现。
如果你想给延迟加载变量加一些初始化或者逻辑处理操作,可以在变量后面加一个闭包调用(闭包的返回值就是变量的默认值)
lazy var tableView: UITableView = {
let tempTableView = UITableView (frame: self.view.bounds, style: .plain)
tempTableView.delegate = self
tempTableView.dataSource = self
tempTableView.register(UITableViewCell.self, forCellReuseIdentifier: cellID)
return tempTableView
}()
( ps:如果你在coding过程中遇到这么个错误,或者是类似的错误,那么是因为你的 ViewController 没有遵守相应的代理导致的。
class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
// ...
}
遵守代理后就可以解决问题。
Cannot assign value of type 'ViewController' to type 'UITableViewDataSource?'
)
也可以实例方法来初始化延迟加载变量:
func initArray() -> Array<String> {
return ["1","2","3"]
}
lazy var dataArray: Array<String> = self.initArray()
也可以使用类方法:
class func initDataArray() -> Array<String> {
return ["1","2","3"]
}
lazy var dataArray: Array<String> = ViewController.initDataArray()
推荐使用在变量后面直接加闭包调用这种写法,代码更加紧凑直观。
swift lazy 变量 只能用 var 关键字来修饰,因为常量必须在实例创建时赋值 。与OC中不同,OC中懒加载变量可以置 nil ,当再次调用的时候依然会重新初始化。因为swift 中 nil 和 OC nil 含义不同(OC中代表空指针,向空指针发送消息不会崩溃,swift 中 nil 代表的是 值缺失 。)所以swift 中懒加载的变量 = nil 时 就相当于直接给他赋值成 nil 了,再次调用该变量时其值就是 nil ,而不会像 OC 中懒加载一样再次初始化!
以上就是 swift 和 OC 中懒加载总结和对比,如果问题欢迎指正。
来源:oschina
链接:https://my.oschina.net/u/2604520/blog/814584