1(Xcode 9.2、Swift 4)から呼び出されると、次の놀え場コードが行2でクラッシュ(EXC_BAD_ACCESS)します。私の考えでは、これは完全に有効なコードです。Swift EXC_BAD_ACCESSプロトコル拡張で定義されているデフォルトの実装
Observable拡張が削除され、addObserverメソッドが代わりに実装クラス(TestObservableImpl)で定義されていると、クラッシュが消えます。
プロトコルTestObservableListenerが削除され、代わりにTestObserverImplがプロトコルTestObservableのObserverでタイプ制約として使用されていると、クラッシュが消えます。
誰かが手がかりを持っているのはなぜですか、これはちょうどスウィフトバグですか?
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では使用できません(プロトコルで作業する必要があります)が、クラッシュを修正するのは間違いありません。 –
私はそれがおそらく解決策ではないことを理解しています。なぜなら、私はこれをコメントとして追加しました。 –