【问题标题】:Updating UIProgressView via delegate method on AudioPlayer通过 AudioPlayer 上的委托方法更新 UIProgressView
【发布时间】:2017-05-30 19:07:22
【问题描述】:

我正在尝试use CADisplayLink to update a UIProgressView。这里是CADisplayLink's initialiation signature

这里是来自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:) 没有暴露于 Objective-C。

很简单...在func updateSlider(sender: AudioPlayer) 前面添加objc,如下所示:

@objc func updateSlider(sender: AudioPlayer)

编译器错误消失一纳秒,然后我刚刚更新的那行说:

@objc 只能与类成员、@objc 协议和 类的具体扩展。

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

我尝试将updateSlider 扔到扩展而不是协议部分,但我不断收到编译器的这个乒乓球,想要在前面添加@objc,然后想要删除它。

我还尝试使用 Timer 类的实例而不是 CADisplayLink 类来执行此操作,但遇到了同样的问题。

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

【问题讨论】:

  • 协议需要标记为@objc,而不是其中的方法。此外,显示链接的目标应为delegate,选择器应为#selector(AudioPlayerDelegate.updateSlider(sender:))。您还应该在将委托传递给显示链接之前将其解包,但是如果您将其传递为零,我不知道该方法实际上做了什么。
  • 就是这样。我解开委托并初始化 CADisplayLink,但声明协议 objc 让我越过了终点线。我只是在声明方法。发布作为声称您 25 岁的答案。:)

标签: ios swift timer avaudioplayer cadisplaylink


【解决方案1】:

Dan 让我在这个问题上越过了终点线。我需要在协议声明前添加@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

【讨论】:

    【解决方案2】:

    它可以这样修复:)

    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)
    }
    

    【讨论】:

      猜你喜欢
      • 2018-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多