2017-05-30 52 views
0

我试图use CADisplayLink to update a UIProgressView。这里的CADisplayLink's initialiation signature通过AudioPlayer上的委托方法更新UIProgressView

下面是从MyAudioPlayer类的相关变量的摘要。

protocol AudioPlayerDelegate: class { 
    func updateSlider(sender: AudioPlayer) 
} 

class AudioPlayer: NSObject { 
    // relevant vars 
    var updater: CADisplayLink? 
    weak var delegate: AudioPlayerDelegate? 

    func play() { 
     // some setup stuff 

     updater = CADisplayLink(target: self, selector: #selector(delegate?.updateSlider(sender:))) 

     // regular stuff to play an audio file 
    } 
} 

当我初始化在play()方法updater,编译器说:

论证#selector指实例方法 updateSlider(sender:)即没有暴露于目标C。

很容易的......在前面加objcfunc updateSlider(sender: AudioPlayer),就像这样:

@objc func updateSlider(sender: AudioPlayer) 

编译器错误消失了纳秒,那么我刚刚更新了行说:

@objc只能用于类的成员,@objc协议和 类的具体扩展。

a few answers covering this topic,但我还没有找到一个工程。

我试着把updateSlider放在一个扩展中而不是在协议部分,但我不断收到编译器的这个ping pong,希望在前面加上@objc,然后想要删除它。

我也尝试使用Timer类的实例来代替CADisplayLink类来做到这一点,但我遇到了同样的问题。

谢谢您的阅读。我欢迎你的建议。

+0

该协议需要标记为@objc,而不是其内部的方法。此外,您的显示链接的目标应该是'delegate'和选择器sho '#selector(AudioPlayerDelegate.updateSlider(sender :))'。在将其传递给显示链接之前,您应该也可能展开您的委托,但如果您通过它,我不知道该方法实际上做了什么。 – dan

+0

就是这样。我打开了委托并初始化了CADisplayLink,但声明了协议objc让我越过了终点。我只是宣布了这个方法。作为一个答案要求你的25。:) – Adrian

回答

0

丹让我在这个问题上的终点线。我只需在委托方法前添加@objc,而不需要在协议声明前添加@objc

// First change 
@objc protocol AudioPlayerDelegate: class { 
    @objc func updateSlider(sender: AudioPlayer) 
} 

AudioPlayer类再往下......

// Delegate declaration 
weak var delegate: AudioPlayerDelegate? 

// Second Change 
if let delegate = delegate { 
    updater = CADisplayLink(target: delegate, selector: #selector(AudioPlayerDelegate.updateSlider(sender:))) 
    updater?.preferredFramesPerSecond = 30 
    updater?.add(to: RunLoop.current, forMode: .commonModes) 
} 

最后,当与updater完成的,而无效和零出来(最有可能在你使用任何方法来阻止你AVAudioPlayer实例

updater?.invalidate() 
    updater = nil 
0

它可以被固定,从而:)

func play() { 
    // some setup stuff 

    updater = CADisplayLink(target: self, selector: #selector(updateSlider(sender:))) 

    // regular stuff to play an audio file 
} 

func updateSlider(sender: AudioPlayer) { 
    delegate?.updateSlider(sender: sender) 
}