异步回调中的递归(Swift)

时间:2018-10-16 03:30:57

标签: ios swift

这里有一些代码旨在使手机振动(异步),等待此任务完成,然后在之后立即使其再次振动:

func vibrate() {
    AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
    AudioServicesAddSystemSoundCompletion(SystemSoundID(kSystemSoundID_Vibrate), nil, nil, { (soundId, clientData) -> Void in
        self.vibrate()
    }, nil)
}

Xcode出现以下错误:

  

A C function pointer cannot be formed from a closure that captures context

如何从该异步函数内部进行递归?

3 个答案:

答案 0 :(得分:1)

我正努力为您的问题找到解决方案,但我偶然发现了以下线程:https://forums.swift.org/t/a-c-function-pointer-cannot-be-formed-from-a-local-function-that-captures-context-on-swift-package/9388/6

我确实将vibrate()方法封装到一个新结构中,如下所示:

import AudioToolbox
import CoreAudioKit

struct Vibrator {
    static func vibrate() {
        AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
        AudioServicesAddSystemSoundCompletion(SystemSoundID(kSystemSoundID_Vibrate), nil, nil, { (soundId, clientData) in
            Vibrator.vibrate()
        }, nil)
    }
}

,当然可以这样称呼它:Vibrator.vibrate()。瞧!

我希望这会有所帮助!

答案 1 :(得分:0)

您也可以使用这种方式来调用类中的任何函数;

AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate)) 
let myData = unsafeBitCast(self, to: UnsafeMutableRawPointer.self) 
AudioServicesAddSystemSoundCompletion(SystemSoundID(kSystemSoundID_Vibrate), 
CFRunLoopGetMain(), nil ,{ (soundId, clientData) in 
let currentSelf = unsafeBitCast(clientData, to: YOUR_CLASS_NAME.self) 
currentSelf.vibrate() // call any funcation from current Controller
}, myData)

答案 2 :(得分:0)

这是我最终找到的解决方案。事实证明,有一个内置函数AudioServicesPlaySystemSoundWithCompletion,该函数以回调作为参数:

func vibrate() {
    AudioServicesPlaySystemSoundWithCompletion(SystemSoundID(kSystemSoundID_Vibrate)) {
        self.vibrate()
    }
}