Swift惰性初始化(lazy)属性(转)

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>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值