Swift延迟加载简单介绍一二

有以下一种情况:

我们试图用Cocoa的语音合成类NSSpeechSynthesizer来完成对字符串的朗读,这很容易.但是我们还有一个附加条件,就是在朗读完一段文本后触发一个动作.

这貌似也不难,我们只要遵守NSSpeechSynthesizerDelegate协议即可,但是光这样还不行,我们还必须将NSSpeechSynthesizer实例的delegate属性设置为合适的委托对象.

作为一个简单的例子,我们会用一个ViewController来作为NSSpeechSynthesizer的委托对象,所以我们可以这样写:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">let</span> speechSythesizer = NSSpeechSythesizer()

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">override</span> func viewDidLoad() {
        super.viewDidLoad()
        speechSynthesizer.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">delegate</span> = self
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

这样很美好,不过非要在viewDidLoad里面赋值委托对象吗?不可以在默认属性中来完成吗?

本猫想了一会,于是有了如下代码:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">let</span> speechSynthesizer:NSSpeechSynthesizer = {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">let</span> tmp = NSSpeechSynthesizer()
        tmp.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">delegate</span> = self
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> tmp
    }()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

不幸的是,以上代码不能正确运行,因为其中的self并没有代表ViewController的实例对象.所以此路不通.

所幸的是Swift为我们提供了一种延时加载(又称惰性加载)属性的机制,我们可以这样写:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">lazy <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> speechSynthesizer:NSSpeechSynthesizer = {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> tmp = NSSpeechSynthesizer()
        tmp.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">delegate</span> = self
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> tmp
    }()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

很好很强大!

需要注意的是lazy修饰的属性初始化代码只会被运行一次,无论你访问该属性多少次!

你可能感兴趣的:(Swift延迟加载简单介绍一二)