Swift中,有两种方式来惰性初始化。 第一种,简单表达式
<code class="hljs scala has-numbering" style="padding: 0px; margin: 0px; display: block; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-color: transparent; background-position: initial initial; background-repeat: initial initial;"> <span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">lazy</span> <span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">var</span> first = NSArray(objects: <span class="hljs-string" style="padding: 0px; margin: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"1"</span>,<span class="hljs-string" style="padding: 0px; margin: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"2"</span>) </code>
- 1
- 2
第二种,闭包
<code class="hljs javascript has-numbering" style="padding: 0px; margin: 0px; display: block; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-color: transparent; background-position: initial initial; background-repeat: initial initial;">lazy <span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">var</span> second:<span class="hljs-built_in" style="padding: 0px; margin: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">String</span> = { <span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="padding: 0px; margin: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"second"</span> }()</code>
- 1
- 2
- 3
注意
- 不要忘记最后的小括号,只有加了小括号,必包才会在掉用的时候立刻执行。
- 要类型声明
lazy var second:String
,这样Xcode会进行类型检查。
三 惰性初始化的使用场景
属性本身依赖于外部因素才能初始化 completeURL表示完整的URL,这个变量依赖于自身的url是否含有http://前缀
<code class="hljs php has-numbering" style="padding: 0px; margin: 0px; display: block; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-color: transparent; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-class" style="padding: 0px; margin: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">Demo</span>{</span> <span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">var</span> url:NSString lazy <span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">var</span> completeURL:NSString = { [unowned <span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">self</span>] in <span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">if</span> <span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">self</span>.url.hasPrefix(<span class="hljs-string" style="padding: 0px; margin: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"http://"</span>){ <span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">self</span>.url }<span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">else</span>{ <span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="padding: 0px; margin: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"http://"</span>.stringByAppendingString(<span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">self</span>.url) } }() init(url:NSString){ <span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">self</span>.url = url } }</code>
属性需要复杂计算,消耗大量CPU
<code class="hljs livecodeserver has-numbering" style="padding: 0px; margin: 0px; display: block; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-color: transparent; background-position: initial initial; background-repeat: initial initial;">lazy var <span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">second</span>:Int = { var <span class="hljs-built_in" style="padding: 0px; margin: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">sum</span> = <span class="hljs-number" style="padding: 0px; margin: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0</span> <span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">for</span> i <span class="hljs-operator" style="padding: 0px; margin: 0px; box-sizing: border-box;">in</span> <span class="hljs-number" style="padding: 0px; margin: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">1.</span>.<span class="hljs-number" style="padding: 0px; margin: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">.100000</span>{ <span class="hljs-built_in" style="padding: 0px; margin: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">sum</span> += i } <span class="hljs-constant" style="padding: 0px; margin: 0px; box-sizing: border-box;">return</span> <span class="hljs-built_in" style="padding: 0px; margin: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">sum</span> }()</code>
属性不确定是否会使用到
<code class="hljs coffeescript has-numbering" style="padding: 0px; margin: 0px; display: block; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-color: transparent; background-position: initial initial; background-repeat: initial initial;">官网的例子,注意,对于Manager来说,使用的时候,可能导入,也可能不倒入数据。从硬盘读取数据的代价是很大的,不导入数据的时候,不要初始化 <span class="hljs-class" style="padding: 0px; margin: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">DataImporter</span> {</span> /* DataImporter <span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">is</span> a <span class="hljs-class" style="padding: 0px; margin: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">to</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">import</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">data</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">from</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">an</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">external</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">file</span>.</span> The <span class="hljs-class" style="padding: 0px; margin: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">is</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">assumed</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">to</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">take</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">a</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">non</span>-<span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">trivial</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">amount</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">of</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">time</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">to</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">initialize</span>.</span> */ <span class="hljs-reserved" style="padding: 0px; margin: 0px; box-sizing: border-box;">var</span> fileName = <span class="hljs-string" style="padding: 0px; margin: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"data.txt"</span> <span class="hljs-regexp" style="padding: 0px; margin: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">//</span> the DataImporter <span class="hljs-class" style="padding: 0px; margin: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">would</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">provide</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">data</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">importing</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">functionality</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">here</span></span> } <span class="hljs-class" style="padding: 0px; margin: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">DataManager</span> {</span> lazy <span class="hljs-reserved" style="padding: 0px; margin: 0px; box-sizing: border-box;">var</span> importer = DataImporter() <span class="hljs-reserved" style="padding: 0px; margin: 0px; box-sizing: border-box;">var</span> data = [String]() <span class="hljs-regexp" style="padding: 0px; margin: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">//</span> the DataManager <span class="hljs-class" style="padding: 0px; margin: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">would</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">provide</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">data</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">management</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">functionality</span> <span class="hljs-title" style="padding: 0px; margin: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">here</span></span> } <span class="hljs-reserved" style="padding: 0px; margin: 0px; box-sizing: border-box;">let</span> manager = DataManager() manager.data.append(<span class="hljs-string" style="padding: 0px; margin: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"Some data"</span>) manager.data.append(<span class="hljs-string" style="padding: 0px; margin: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"Some more data"</span>)</code>
定制化的初始化 有些初始化只需要初始化一次,在变量定义的地方初始化,有助于代码维护
<code class="hljs lasso has-numbering" style="padding: 0px; margin: 0px; display: block; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-color: transparent; background-position: initial initial; background-repeat: initial initial;">lazy <span class="hljs-built_in" style="padding: 0px; margin: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">var</span> dataArray:NSMutableArray <span class="hljs-subst" style="padding: 0px; margin: 0px; color: rgb(0, 0, 0); box-sizing: border-box;">=</span> { <span class="hljs-built_in" style="padding: 0px; margin: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">var</span> <span class="hljs-built_in" style="padding: 0px; margin: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">array</span> <span class="hljs-subst" style="padding: 0px; margin: 0px; color: rgb(0, 0, 0); box-sizing: border-box;">=</span> NSMutableArray() for i <span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">in</span> <span class="hljs-number" style="padding: 0px; margin: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">1.</span><span class="hljs-built_in" style="padding: 0px; margin: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">..</span><span class="hljs-number" style="padding: 0px; margin: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">100</span>{ <span class="hljs-built_in" style="padding: 0px; margin: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">array</span><span class="hljs-built_in" style="padding: 0px; margin: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">.</span>addObject(NSNumber(<span class="hljs-built_in" style="padding: 0px; margin: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">integer</span>: i)) } <span class="hljs-keyword" style="padding: 0px; margin: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-built_in" style="padding: 0px; margin: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">array</span> }()</code>