私は例を見つけようとしてきましたが、私の場合は見たことがうまくいきません。
次のコードに相当するものは何ですか:
object.addObserver(self, forKeyPath: "keyPath", options: [.new], context: nil)
override public func observeValue(
forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?) {
}
上記のコードは機能しますが、SwiftLinkから警告が表示されます。
Swift 3.2以降を使用する場合は、キーパスを使用した新しいブロックベースのKVO APIを優先してください。
あなたが私を正しい方向に向けることができれば感謝しています。
Swift 4は、具体的なファミリー Key-Path types 、新しい Key-Path Expression を導入し、新しいクロージャーベースの observe 関数を導入しましたNSObject
を継承するクラスで使用できます。
この新しい機能セットを使用すると、特定の例をより簡潔に表現できます。
self.observation = object.observe(\.keyPath) {
[unowned self] object, change in
self.someFunction()
}
関与するタイプ
observation:
NSKeyValueObservation
change:
NSKeyValueObservedChange
\.keyPath
:コンパイル時に生成される KeyPath クラスのインスタンス。キーパス文法
キーパス式の一般的な 文法 は、\Type.keyPath
という形式に従います。ここで、Type
は具体的な型名(一般的なパラメータを含む)、keyPath
は1つ以上のプロパティ、添え字のチェーンです、またはオプションのチェーン/強制的なアンラップ後置。さらに、keyPathのTypeをコンテキストから推測できる場合は省略でき、最も簡潔な\.keyPath
になります。
これらはすべて有効なキーパス式です。
\SomeStruct.someValue
\.someClassProperty
\.someInstance.someInnerProperty
\[Int].[1]
\[String].first?.count
\[SomeHashable: [Int]].["aStringLiteral, literally"]!.count.bitWidth
所有権
あなたはNSKeyValueObservation
関数が返すobserve
インスタンスの所有者です。つまり、する必要はありませんaddObserver
もremoveObserver
もありません。むしろ、観察を観察する必要がある限り、それに対する強い参照を保持します。
あなたはnotのいずれかinvalidate()
を必要としています:それはdeinit
に優雅になります。そのため、それを保持しているインスタンスが死ぬまでライブにするか、参照をnil
ingすることで手動で停止するか、何らかの臭い理由でインスタンスを生き続ける必要がある場合はinvalidate()
を呼び出すこともできます。
注意事項
お気づきかもしれませんが、観察はまだCocoaのKVOメカニズムの範囲内に潜んでいるため、NSObject
(Swift-devのお気に入りの型すべて)を継承するObj-CクラスおよびSwiftクラスでのみ利用できます。観察するつもりなら、@objc
(Swift-devのお気に入りの属性ごと)としてマークし、dynamic
を宣言する必要があります。
そうは言っても、全体的なメカニズムは歓迎すべき改善です。特に、使用する必要があるモジュール(NSObjects
など)からインポートされたFoundation
をSwiftifyが監視し、表現力を弱めることなく取得するのが難しいためです。すべてのキーストロークで。
サイドノートとして、 Key-PathStringExpressions はまだ必要です 動的にアクセスNSObject
's KVCのプロパティ、またはvalue(forKey(Path):)
の呼び出し
KVOを超えて
キーパス式には、KVOよりもはるかに多くのことがあります。 \Type.path
式は、後で再利用するためにKeyPath
オブジェクトとして保存できます。書き込み可能、部分消去、タイプ消去のフレーバーがあります。彼らは、レンズとプリズムのような機能的概念の世界を掘り下げることを可能にすることに加えて、作曲のために設計されたゲッター/セッター機能の表現力を増強することができます。以下のリンクをチェックして、開くことができる多くの開発の扉について詳しく知ることをお勧めします。
リンク:
Key-Path Expression @ docs.Swift.org
Swift Evolution Smart KeyPathsの提案
キーパスの例があるOle BegemannのWhats-new-in-Swift-4プレイグラウンド
WWDC 2017ビデオ:Foundationの新機能SKPの場合は4:35、KVOの場合は19:4
IOS 10でこの方法を使用すると、アプリでクラッシュが発生したため、答えに何かを追加します。
IOS 10では、クラスの割り当てを解除する前にオブザーバーを削除する必要があります。そうしないと、次のことを示すクラッシュNSInternalInconsistencyException
が発生します。
クラス
A
のインスタンスC
は、キー値オブザーバーがまだ登録されている間に割り当て解除されました。
このクラッシュを避けるため。使用しているオブザーバープロパティをnil
に設定するだけです。
deinit {
self.observation = nil
}