問題タブ [objective-c-swift-bridge]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
swift - 依存するキー パスの KVO が Swift クラスで正しく機能しない
URLSessionTask
Swiftでラッパーを書き込もうとしています。ドキュメントによると
すべてのタスク プロパティは、キーと値の監視をサポートしています。
したがって、この動作を維持し、ラッパーのすべてのプロパティも KVO に準拠し (通常はラップされたタスクに委任)、Objective-C に完全にアクセスできるようにしたいと考えています。1 つのプロパティで何を行っているかを説明しますが、基本的にはすべてのプロパティで同じことを行いたいと考えています。
state
の性質をとってみましょうURLSessionTask
。次のようにラッパーを作成します。
@objc
Objective-C から呼び出せるようにプロパティを追加しました。そして、プロパティに追加dynamic
して、Swift からでもメッセージ パッシング/ランタイム経由で呼び出されるようにして、正しい KVO 通知が によって生成されるようにしましたNSObject
。"Using Swift with Cocoa and Objective-C" book の Apple の KVO の章によると、これで十分なはずです。
次に、 KVO に依存キー パスを伝えるために必要な静的クラス メソッドを実装しました。
次に、通知が正しく呼び出されるかどうかを確認する単体テストを作成しました。
実行すると、テストは次のようにクラッシュしますNSInternalInconsistencyException
。
*** キャッチされない例外 'NSInternalInconsistencyException' が原因でアプリを終了します。適切な KVO 通知が送信されずに変更されました。MyURLSessionTask クラスの KVO 準拠を確認してください。
しかし、underlyingTask
-property@objc
とを作成することdynamic
で、Objective-C ランタイムは、タスクが Swift から変更された場合でも、この通知が送信されるようにする必要がありますよね?
次のように、underlyingTask の KVO 通知を手動で送信することで、テストを正しく機能させることができます。
しかし、すべてのプロパティにこれを実装する必要はなく、既存のkeyPathsForValuesAffecting<Key>
メソッドを使用することをお勧めします。これを機能させるために何か不足していますか?それともうまくいくはずで、これはバグですか?