懒加载的好处自然不必多说,在使用到对象的时候才会进行创建,这样会减少内存的压力提高运行性能..
Swift在声明属性时候因为有lazy的存在可以顺便声明为懒加载,没有OC声明懒加载的冗杂代码,这就更让我养成了"是个属性就用懒加载搞个初始化"的习惯.
但是今天就因为一个属性使用了懒加载导致了一个潜在难以定位的bug..
在做下载器的时候需要用到OutputStream
将数据保存到一个路径下而且要控制输出流的打开和关闭,所以要将其声明为属性
因为构造方法需要我传入一个路径地址,这个路径地址是另外一个属性,我为了省事快捷所以用了lazy,这样可以在创建它的使用传入我想要的路径self.downloadingPath
fileprivate lazy var outputStream: OutputStream = {
OutputStream(toFileAtPath: self.downloadingPath, append: true)!
}()
接着,在想要打开传输的地方调用outputStream.open()
和outputStream.write(pointer, maxLength: data.count)
即可
这样写走一遍下来是没有问题的.文件保存到了我想要的路径中.
But
- 下载器中有一个"取消"的功能,在取消后面我调用了
outputStream.close()
但用户取消之后还可能重新下载..同样的路径,再调用outputStream.open()
后,发现本地文件的大小不会再增加了. 而在第二次open前重新创建OuputStream指定路径或者不调用close可以解决此问题,...说明在close之后想要重新开启输出流是要再次指定路径了,而我因为用lazy声明了改属性,自以为会保证outputstrem的路径一直都会是不变而且存在的.. - 除了调用
outputStream.close()
还有种情况需要重新创建outputStream并指定路径,下载器中有"取消下载并删除文件"的操作,它会将"downloadPath"移除,这个时候重新下载该文件会发现并下载不下来.outputStream指定的路径作废了(虽然我觉得这样很不合理).
所以对于这样并不太常用的自己无法掌控的类,而且还有close这样的方法,用懒加载的时候要考虑清楚你的构造方法只会调用一次,而只调用一次会不会对后面的各种状态产生影响.同理如果lazy里面放了很多的初始化代码..那些都只会调用一次.有时候要规避不可预知的错误可以考虑不用懒加载.