Swift延迟加载简单介绍一二

本文介绍了在Swift中如何实现延迟加载(惰性加载)属性,以解决在使用NSSpeechSynthesizer进行语音合成就完成后触发动作的需求。通过遵守NSSpeechSynthesizerDelegate并设置委托对象,作者发现直接在默认属性中设置委托存在问题。最后,通过Swift的lazy关键字实现了延迟加载,确保初始化代码只执行一次,解决了问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有以下一种情况:

我们试图用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修饰的属性初始化代码只会被运行一次,无论你访问该属性多少次!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值