【发布时间】:2018-03-01 15:14:22
【问题描述】:
我刚刚更新到 Swift 4 和 Xcode 9,并收到以下代码的 (swiftlint) 警告,告诉我现在应该使用 KVO:
警告:
(基于块的 KVO 违规:更喜欢新的基于块的 KVO API 使用 Swift 3.2 或更高版本时的键路径。 (block_based_kvo))
旧代码:
override func observeValue(forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?) {
if keyPath == "outputVolume"{
guard let newKey = change?[NSKeyValueChangeKey.newKey] as? NSNumber else {
fatalError("Could not unwrap optional content of new key")
}
let volume = newKey.floatValue
print("volume " + volume.description)
}
}
我尝试修复:
let audioSession = AVAudioSession.sharedInstance()
audioSession.observe(\.outputVolume) { (av, change) in
print("volume \(av.outputVolume)")
}
Apple 声称 here 大部分属性应该是 dynamic(我知道这是 AVPlayer 而不是 AVAudioSession)。我查了一下,但在 AVPlayer 属性中找不到任何 dynamic 语句,我想知道它是如何工作的(如果我没记错的话,这些是 KVO 工作所必需的)。
编辑:
我不确定它是否不会触发,因为它根本不起作用,或者是由于我尝试存档的原因。一般来说,我希望收到有关通过推动硬件音量摇杆触发的音量变化的通知。
【问题讨论】:
-
您的尝试似乎有效,但不要忘记使用或不使用观察函数的返回值。不想用的可以这样
_ = audioSession.observe(\.outputVolume) { (av, change) in print("volume \(av.outputVolume)") } -
我试过了,但不幸的是它似乎没有触发。由于某种原因,代码没有被执行。也许我错过了什么。
-
这在模拟器中有效吗?因为我已经尝试了所有方法,并且从未调用过观察回调。
-
不,这在 siuulator 中不起作用。在设备上为我工作。
-
我终于得到了这个工作(iOS 14/SDK 12)。正如其他人指出的那样,您需要在
observe()之前致电AVAudioSession.sharedInstance().setActive(true)。但是,就我而言,仅此一项并不能解决问题。我不得不在两个电话之间放置一些分隔。在init()中设置会话处于活动状态,然后在稍后的方法中设置observe()。我相信dispatch_after也会解决它。
标签: ios key-value-observing swift4 xcode9 swiftlint