IOS KVC(キー値符号化)モード

5105 ワード


IOSでは、メソッドと変数を含む絶対的なプライベートはありません.プライベートメソッドはクラスインスタンスから直接アクセスできませんが、「コンパイル時に実行」メカニズムがあるため、perfromSelectoeのようなメソッドでプライベートメソッドにアクセスできます.IOSのプライベート変数はいわゆるKVCモードでもアクセス可能である.次はクールバーでIOS KVCモードの使い方を整理しました.
KVCモードはkey-value coding(キー値符号化)であり、文字列識別を用いてオブジェクト属性に間接的にアクセスする原理である.キーメソッドはNSKeyValue Codingprotocolで定義されています.KVCはクラスオブジェクトと組み込み基本データ型をサポートする.私たちは主に2つの方法を使用しています.
1,setValue:forKey,valueForKey;NSString属性の名前を入力
2,setValue:forKeyPath,valueForKeyPath(NSStringプロパティへのパス、xx.xx形式)
注意:
KVCでオブジェクトを呼び出すと、[self valueForKey:@"tekuba";
プログラムは自動的にいくつかの異なる方法でこの呼び出しを解析しようとします.まず、tekubaというメソッドとgetTekubaがあるかどうかを検索します.tekubaおよび_getTekubaといういくつかの形式は、見つからない場合はtekubaというインスタンス変数(iVar)があるかどうかを検索し続け、まだ見つからない場合は-(id)valueForUndefinedKey:この方法を呼び出し続けます.この方法がまだ実装されていない場合、プログラムはNSUndefinedKeyException異常エラー(確認対象)を放出します.
設計valueForUndefinedKey:メソッドの主な目的は、-(id)valueForKeyメソッドを使用してオブジェクトから値を要求すると、オブジェクトがエラーが発生する前に、このリクエストに応答する最後の機会を持つことです.
次の例を参照してください.
ヘッダファイルh
#import<Foundation/Foundation.h>
@interface TekubaNet:NSObject
{
    NSString *url;
}
@end
実装ファイル
#import"TekubaNet.h"
@implementation TekubaNet
@end
このTekubaNetクラスは簡単でurl変数は1つしかありません.この場合、TekubaNetのクラスインスタンスからurlにアクセスすることはできません.
次に、KVCモードを使用してurlにアクセスします.次のようになります.
int main (int argc, const char * argv[]) {  
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];  
    TekubaNet *tekubaNet=[[TekubaNet alloc] init];  
    [tekubaNet setValue:@"http://www.tekuba.net" forKey:@"url"];  
    NSString *url=[book valueForKey:@"url"];  
    NSLog(@"tekuba url= %@",url);  
    [pool release];  
    return 0;  
}  
コードについて補足します.
Webmasterクラスを定義します.
ヘッダファイルh
#import<Foundation/Foundation.h>
@interface Webmaster:NSObject
{
    NSString *name;
}
@end
実装ファイル
#import"Webmaster.h"
@implementation Webmaster
@end
WebmasterをTekubaNetクラスに追加します.次のようにします.
#import<Foundation/Foundation.h>
@interface TekubaNet:NSObject
{
    Webmaster *webmaster;
    NSString *url;
}
@end
TekubaNetの実装ファイルは変更されません.
次に、KVCモードを使用してTekubaNetのwebmasterのnameプロパティにアクセスする方法を示します.
int main (int argc, const char * argv[]) {  
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];  
    TekubaNet *tekubaNet=[[[TekubaNet alloc] init] autorelease];  
    [tekubaNet setValue:@"http://www.tekuba.net" forKey:@"url"];  
    NSString *url=[tekubaNet valueForKey:@"url"];  
    NSLog(@"tekuba url: %@",url);  
    Webmaster *webmaster=[[[Webmaster alloc] init] autorelease];  
    [webmaster setValue:@" " forKey:@"name"];  
    [tekubaNet setValue:webmaster forKey:@"webmaster"];  
    NSString *name=[tekubaNet valueForKeyPath:@"webmaster.name"]; /* IOS path*/  
    NSLog(@"webmaster name: %@",name);  
    [pool release];  
    return 0;  
}  
さらに、KVCには、文字列に基づいて適切なデータ型に自動的に変換されるという自動梱包機能が重要です.たとえば、次のようになります.
@interface TekubaNet:NSObject
{
    Webmaster *webmaster;
    NSString *url;
    int runDay;
}
では、以前の方法でアクセスできます.
[tekubaNet setValue:@"365" forKey:@"runDay"]; 
NSLog(@"tekubaNet runTime is %@",[tekubaNet valueForKey:@"runDay"]); 
runDayはint型ですが、私たちは同じように%@で印刷できます.
(1)setValue:forKeyの検索方法:
まずset:メソッドを検索します.メンバーが@property,@synthsizeで処理されている場合、@synthsizeはコンパイラにset:フォーマットのsetterメソッドを自動的に生成するように伝えているため、この場合は直接検索されます.注意:ここのはメンバー名で、頭文字が大文字です.以下同.
上記のsetterメソッドが見つかりませんでした.クラスメソッドaccess InstanceVariablesDirectlyがYESを返す場合(注:NSKeyValueCodingCatogeryで実装されているクラスメソッドで、デフォルトではYESを返すように実装されています).では_,_is,,isの順にメンバー名を検索します.
設定メンバーの値が見つかった場合、setValue:forUndefinedKey:が呼び出されていない場合.
(2)valueForKey:の検索方法:
1.まずget、isの順にgetterメソッドを検索し、直接呼び出しを見つけます.bool、intなどの組み込み値タイプであればNSNumberの変換が行われます.
2.上のgetterが見つかりませんでした.countOf、objectInAtIndex:、AtIndexes形式のメソッドを検索します.
countOfと他の2つのメソッドのいずれかが見つかった場合、NSArrayのすべてのメソッドに応答できるエージェントセット(collection proxy object)が返されます.このエージェントセット(collection proxy object)に送信されるNSArrayメッセージメソッドはcountOf,objectInAtIndex:,AtIndexesといういくつかのメソッドの組合せで呼び出される.オプションのget:range:メソッドもあります.
3.まだ調べていない場合、countOf、enumeratorOf、memberOf:フォーマットの方法を検索します.
これら3つのメソッドが見つかった場合、NSSetのすべてのメソッドに応答できるエージェントセット(collection proxy object)が返されます.このエージェントセット(collection proxy object)に送信されるNSSetメッセージメソッドは、countOf、enumeratorOf、memberOf:を組み合わせて呼び出されます.
4.まだ検出されていない場合、クラスメソッドがYESを返す場合は、を押します.key>,_is,,isの順でメンバー名を直接検索します.
5.これ以上調べられず、valueForUndefinedKey:.
特酷吧,本站地址:www.tekuba.net/program/294/