[KVC翻訳]2.1-Key-Value Coding Programming Guide公式ドキュメント第2部
7531 ワード
Key-Value Coding Programming Guide公式ドキュメント第2部第1節2018.9.20第1回修正
iOS-KVC公式ドキュメント第2部第1節
Key-Value Coding Fundamatals--Accessing Object Properties
属性.単純な値、たとえばスカラー( 一対一の関係独自の属性を持つ可変オブジェクトを指します.オブジェクトのプロパティは、オブジェクト自体が変わらない場合に変更できます.たとえば、銀行口座オブジェクト(bank account object)には、addressプロパティを持つPersonオブジェクトのインスタンスであるownerプロパティがある場合があります.ownerのaddressは、銀行口座が保有するownerを変更することなく変更される可能性があります.銀行口座のownerは変更されていません.Personのaddressだけが変わった. 一対多の関係.集合オブジェクトを指します.通常は
インベントリ2-1に宣言された
リスト2-1
カプセル化を維持するために、オブジェクトは通常、インタフェースのプロパティにアクセスメソッドを提供します.オブジェクトの作成者は、これらの方法を明示的に記述したり、コンパイラに依存して自動的に合成したりすることができます.いずれにしても、これらのアクセサの1つを使用するコードの作成者は、コンパイルする前にプロパティ名をコードに書き込む必要があります.アクセサメソッドの名前は、そのコードを使用する静的部分となります.たとえば、インベントリ2-1に宣言されているBankAccountオブジェクトを指定すると、コンパイラはmyAccountインスタンスに対して呼び出すことができるsetterを合成します.
これは直接的ですが、柔軟性に欠けています.一方、キー値符号化に適合するオブジェクトは、文字列識別子を使用してオブジェクト属性にアクセスするより一般的なメカニズムを提供する.
キー(
リスト2-1の
実際には、myAccountオブジェクトのすべてのプロパティを同じ方法で異なるキーパラメータで設定できます.パラメータは文字列タイプであるため、実行時に変数を操作できます.
キーパス
例えば、銀行口座インスタンスに適用されるキーパス
なお、Swiftでは、文字列を使用してキーまたはキーパスを示すのではなく、
オブジェクトは、
注意集合オブジェクト(例えば
KeyPathを使用してプロパティをアドレッシングする場合、キーパスの最後のキーが1対のマルチリレーションシップ(すなわち参照セット)である場合、マルチペアのキーの右側には、キーのすべての値を含むセットが返されます.例えば、要求キーパス「
受信
デフォルトのインプリメンテーションでは、非オブジェクト属性を
keyベース
インベントリ2-2キー値に基づいて符号化されないデータソース方法の実現
一方、リスト2−3は、キー値符号化互換性のある
インベントリ2-3キー値符号化に基づくデータソース方法の実現
筆者のレベルが限られているため、文の中に間違いがあったり、もっと良い方法があったりしたら、大神さんに指摘してもらいたい.本文のすべてのdemoダウンロードリンクを添付し、【GitHub】.見終わったら役に立つと思ったら、GitHubでstarを注文してください.人にバラを贈り,手に余香がある.
iOS-KVC公式ドキュメント第2部第1節
Key-Value Coding Fundamatals--Accessing Object Properties
キー値エンコーディングベース--オブジェクトのプロパティにアクセス
オブジェクト属性へのアクセス
オブジェクトは、通常、インタフェース宣言でプロパティを指定します.これらのプロパティは、次のカテゴリのいずれかに属します.
scalars
)、文字列またはブール値を指します.値オブジェクト(例えばNSNumber
)やその他の可変タイプ(例えばNSColor
)も属性とみなされる.NSArray
またはNSSet
このようなコレクションのインスタンスを保存しますが、カスタムコレクションクラスを使用することもできます.インベントリ2-1に宣言された
BankAccount
オブジェクトは、各タイプの属性を示す.リスト2-1
BankAccount
オブジェクトの属性@interface BankAccount : NSObject
@property (nonatomic) NSNumber* currentBalance; // An attribute
@property (nonatomic) Person* owner; // A to-one relation
@property (nonatomic) NSArray* transactions; // A to-many relation
@end
カプセル化を維持するために、オブジェクトは通常、インタフェースのプロパティにアクセスメソッドを提供します.オブジェクトの作成者は、これらの方法を明示的に記述したり、コンパイラに依存して自動的に合成したりすることができます.いずれにしても、これらのアクセサの1つを使用するコードの作成者は、コンパイルする前にプロパティ名をコードに書き込む必要があります.アクセサメソッドの名前は、そのコードを使用する静的部分となります.たとえば、インベントリ2-1に宣言されているBankAccountオブジェクトを指定すると、コンパイラはmyAccountインスタンスに対して呼び出すことができるsetterを合成します.
[myAccount setCurrentBalance:@(100.0)];
これは直接的ですが、柔軟性に欠けています.一方、キー値符号化に適合するオブジェクトは、文字列識別子を使用してオブジェクト属性にアクセスするより一般的なメカニズムを提供する.
KeysとKeyPathsを使用してオブジェクトのプロパティを識別
キー(
key
)は、特定の属性を識別する文字列です.通常、慣例に従って属性を表すキー(key
)は、コードに表示される属性名である.キー(key
)は、ASCII
コードを使用する必要があります.スペースは含まれず、通常は小文字で始まります(多くのクラスのURL
プロパティなどの例外がありますが).リスト2-1の
BankAccount
クラスはキー値に適合して符号化されているため、キー(すなわちその属性の名称)owner
currentBalance
・およびtransactions
を識別することができる.呼び出しではなく、そのキーで値を設定することもできますsetCurrentBalance:
メソッド:[myAccount setValue:@(100.0) forKey:@"currentBalance"];
実際には、myAccountオブジェクトのすべてのプロパティを同じ方法で異なるキーパラメータで設定できます.パラメータは文字列タイプであるため、実行時に変数を操作できます.
キーパス
Key path
は、ポイントオペレータ.
でキーを区切る文字列で、巡回するオブジェクト属性シーケンスを指定します.シーケンス内の最初のキーのプロパティは受信者に対して、各後続のキーは前のプロパティの値に対して計算されます.キーパス(Key path
)は、単一のメソッドを使用してオブジェクトを深く呼び出す階層に役立ちます.例えば、銀行口座インスタンスに適用されるキーパス
owner.address.street
は、銀行口座所有者アドレスに格納されている街文字列の値であり、仮定Person
およびAddress
クラスも一致するキー値符号化である.なお、Swiftでは、文字列を使用してキーまたはキーパスを示すのではなく、
#keyPath
式を使用できます.これは、Using Swift with Cocoa and Objective-C(Swift 4.2)のKeys and Key Paths章を参照して、コンパイル時のチェックの利点を提供します.キーを使用した属性値の取得
オブジェクトは、
NSKeyValueCoding
プロトコルに従うときにキー値符号化に適合する.継承されたオブジェクト(NSObject
プロトコルの基本メソッドのデフォルト実装を提供)は、このプロトコルのデフォルト動作の一部を自動的に採用します.このようなオブジェクトは、少なくとも以下のキーベースの基本getterを実現します.valueForKey:
-keyパラメータで指定した属性の値を返します.アクセス者検索モードで記述されたルールに従ってkey名の属性が見つからない場合、オブジェクトは自身にvalueForUndefinedKey:
メッセージを送信します.valueForUndefinedKey:
発生したデフォルト実装放出NSUndefinedKeyException
異常ですが、サブクラスはこの方法を上書きし、より優雅に処理できます.valueForKeyPath:
-受信機に対する指定キーパスの値を返します.keyPathシーケンスのいずれのオブジェクトも、特定のkeyのキー値符号化に合致しない-すなわち、デフォルト実装valueForKey:
アクセスメソッドが見つからない--では、valueForUndefinedKey:
メッセージが受信される.dictionaryWithValuesForKeys:
-受信機のキーのセットに対応する値を返します.この方法は配列内の各キー呼び出しvalueForKey:
である.返されるNSDictionary
配列内のすべてのキーの値を含む.注意集合オブジェクト(例えば
NSArray
・NSSet
およびNSDictionary
)にはnilの値は含まれません.NSNullオブジェクトを使用してnil値を表します.NSNullは、オブジェクトのプロパティのnil値を表す単一のインスタンスを提供します.dictionaryWithValuesForKeys:
のデフォルト実装と関連するsetValuesForKeysWithDictionary:
NSNull(ディクショナリパラメータ内)とnil(格納された属性内)の間で自動変換されます.KeyPathを使用してプロパティをアドレッシングする場合、キーパスの最後のキーが1対のマルチリレーションシップ(すなわち参照セット)である場合、マルチペアのキーの右側には、キーのすべての値を含むセットが返されます.例えば、要求キーパス「
transactions.payee
」の値は、全てtransaction
オブジェクトのうちpayee
オブジェクトを含む配列を返す.これは、KeyPathの複数の配列にも適用されます.KeyPathaccounts.transactions.payee
すべての勘定科目のすべての取引のすべての受取人オブジェクトを含む配列を返します.キーを使用した属性値の設定
getter
と同様に、キー値符号化に適合するオブジェクトにも共通setterのセットが設けられており、そのデフォルト動作は以下のNSKeyValueCoding
プロトコルの実装NSObject
に基づいている.setValue:forKey:
-指定キーを所定値に設定します.setValue:forKey:
のデフォルトインプリメンテーションでは、スカラーと構造体を表すNSNumber
およびNSValue
オブジェクトに対して自動的に
操作を行い、対応する属性に設定します.パッケージ(warp)およびアンパッケージ(unwarp)の意味の詳細については、Representing Non-Object Valueを参照してください.受信
setter
呼び出したオブジェクトに指定キーに対応する属性がない場合、そのオブジェクトは自分に[setValue:forUndefinedKey:]
メッセージを送信する.setValue:forUndefinedKey:
のデフォルト実装が投げ出されるNSUndefinedKeyException
異常.ただし、サブクラスは、このメソッドを書き換えてリクエストをカスタマイズして処理できます.setValue:forKeyPath:
受信者に対する指定キーパスに所定値を設定する.キーパスシーケンスで指定されたキーに対応するオブジェクトがキー値符号化互換性がない場合、setValue:forUndefinedKey:
メッセージが受信されます.setValuesForKeysWithDictionary:
指定辞書の値を受信者の属性に設定し、辞書キーを使用して属性を識別する.デフォルト実装では、各キー値ペアを呼び出すsetValue:forKey:
、必要に応じてnil
置換NSNull
オブジェクトを使用します.デフォルトのインプリメンテーションでは、非オブジェクト属性を
nil
値に設定しようとすると、キー値符号化互換オブジェクトは、setNilValueForKey:
メッセージを自分で送信します.setNilValueForKey:
のデフォルトインプリメンテーションから放出される[NSInvalidArgumentException]
例外ですが、オブジェクトはこのメソッドを書き換えてデフォルト値またはタグ値を置き換えることができます.詳細は、非オブジェクト値の処理を参照してください.キーを使用したオブジェクトアクセスのシンプル化
keyベース
getter
およびsetter
コードの簡略化方法については、次の例を参照してください.macOSでは、NSTableView
およびNSOutlineView
オブジェクトの識別子文字列がそれぞれの列に関連付けられている.テーブルのモデル・オブジェクトがキー値符号化に合致しない場合、テーブルのデータ・ソース・メソッドは、リスト2-2に示すように、各カラム識別子を強制的にチェックし、返される正しい属性を順次検索します.また、将来的には、モデルに別の属性を追加する場合、この例ではPerson
オブジェクトである、データソースメソッドに再アクセスし、新しい属性をテストして相関値を返す別の条件を追加する必要がある.インベントリ2-2キー値に基づいて符号化されないデータソース方法の実現
- (id)tableView:(NSTableView *)tableview objectValueForTableColumn:(id)column row:(NSInteger)row {
id result = nil;
Person *person = [self.people objectAtIndex:row];
if ([[column identifier] isEqualToString:@"name"]) {
result = [person name];
} else if ([[column identifier] isEqualToString:@"age"]) {
result = @([person age]); // Wrap age, a scalar, as an NSNumber
} else if ([[column identifier] isEqualToString:@"favoriteColor"]) {
result = [person favoriteColor];
} // And so on...
return result;
}
一方、リスト2−3は、キー値符号化互換性のある
Person
オブジェクトを用いた同じデータソースの方法のよりコンパクトな実装を示している.valueForKey:
getterのみを使用し、データソースメソッドはカラム識別子をキーとして適切な値を返します.新しいカラムを後で追加するときに、カラム識別子が常にモデルオブジェクトのプロパティ名と一致する限り、カラム識別子は変わらないため、より短い時間に加えて一般的です.インベントリ2-3キー値符号化に基づくデータソース方法の実現
- (id)tableView:(NSTableView *)tableview objectValueForTableColumn:(id)column row:(NSInteger)row {
return [[self.people objectAtIndex:row] valueForKey:[column identifier]];
}
筆者のレベルが限られているため、文の中に間違いがあったり、もっと良い方法があったりしたら、大神さんに指摘してもらいたい.本文のすべてのdemoダウンロードリンクを添付し、【GitHub】.見終わったら役に立つと思ったら、GitHubでstarを注文してください.人にバラを贈り,手に余香がある.