【发布时间】:2017-12-20 16:54:17
【问题描述】:
以下 Playground 代码在从 1(Xcode 9.2,Swift 4)调用时会导致第 2 行崩溃(EXC_BAD_ACCESS)。在我看来,这是完全有效的代码。
当 Observable 扩展被移除并且 addObserver 方法被定义在实现类中(TestObservableImpl)时,崩溃消失了。
如果协议 TestObservableListener 被移除,并且在协议 TestObservable 中将 TestObserverImpl 用作 Observer 的类型约束,崩溃也会消失。
有没有人知道为什么,或者这只是一个 Swift 错误?
public protocol Observable: class {
associatedtype Observer: AnyObject
var observers: [Observer] { get set }
func addObserver(_ observer: Observer) -> Void
}
public extension Observable {
public func addObserver(_ observer: Observer) -> Void {
observers.append(observer)
}
}
protocol TestObservableListener: class {
func bla()
}
protocol TestObservable: Observable where Observer == TestObservableListener {
}
class TestObservableImpl: TestObservable {
typealias Observer = TestObservableListener
public var observers = [Observer]()
func broadcast() {
for observer in observers {
//2
observer.bla()
}
}
}
class TestObserverImpl: TestObservableListener {
func bla() {
print("bla")
}
}
let observable = TestObservableImpl()
let observer = TestObserverImpl()
observable.addObserver(observer)
//1
observable.broadcast()
【问题讨论】:
-
快速浏览了一下,这也将解决问题:
(observer as! TestObserverImpl).bla()所以看起来可怜的旧运行时很难确定观察者对象的实际类型。 -
你说得对,它确实修复了崩溃,但是在实际场景中,TestObservableImpl 无法使用具体类型(需要在协议上工作)。
-
我意识到这可能不是一个解决方案,这就是为什么我将它添加为评论而不是答案我只是认为它可能指向一个原因,因为我没有时间进一步调查。