2012-02-13 1 views
7

NSDictionaryのキーの値にアクセスするためのドット表記法はありますか?NSDictionaryにドット表記でアクセスしますか?

NSDictionary *returnVal = [NSDictionary dictionaryWithObjectsAndKeys:@"Saturn", @"name", @"Gas Giant", @"type", nil]; 
NSLog(@"VALUE: %@", [returnVal valueForKey:@"name"]); // This is how I am doing it now. 
+0

私はあなたがカテゴリを使ってドット表記法を使用できるようにするつもりです。 –

+4

@ RichardJ.RossIII私はあなたがカテゴリーで答えなければならないとは思わない。いくつかのObj-C機能を示していますが、これはかなり悪い習慣です。おそらく、 'NSObject'のサブクラスであるモデルオブジェクトを提案するほうが良いアプローチでしょう。 –

+1

コンパイラがドットを拒否するので、あなたが ' - (id)valueForUndefinedKey: 'を上書きして何かできることは疑問です... – JustSid

答えて

1

いいえ、それは正しい方法です。 iOSの世界では、しばしば正しい方法が唯一の方法です。あなたが本当にドット表記(とあなたが型付きオブジェクトを取得し、他の素敵なものを)したい場合:)

、あなたがオブジェクトに辞書表現を詰め込むする必要があるとしています。最も一般的には私のインターフェイスは次のようになります:

@interface FooBar : NSObject { 
    NSString *someData; 
    int someNumber; 
} 

@property (nonatomic, copy) NSString *someData; 
@property (nonatomic, assign) int someNumber; 

+ (FooBar *)FooBarFromDictionary:(NSDictionary *)dataDict; 

@end 

実装は明確です。次にできること

FooBar *fb = [FooBar FooBarFromDictionary:data]; 
NSLog(@"fb.someData = %@", fb.someData); 
+0

技術的にはありません。あなたはブロックやカテゴリでかなりクレイジーなことをすることができます、私の答えを見てみましょう。 –

1

いいえ、私はそうは思わない。

リファレンスマニュアルから。

Accessing Keys and Values 
– allKeys 
– allKeysForObject: 
– allValues 
– getObjects:andKeys: 
– objectForKey: 
– objectsForKeys:notFoundMarker: 
– valueForKey: 

これは、キーと値にアクセスする唯一の方法として挙げられています。あなたはそれをうまくやっている。

公開鍵で公開されていれば、アクセスできます。

6

ありNSDictionaryには、ドット構文はありませんが、あなたが辞書の要素にアクセスするために言及した方法は、理想的な方法(キーを使用)である代わりにvalueForKey:

Difference between objectForKey and valueForKey?

+0

ありがとう、私はそれを行うだろう、私は違いが何だったのだろうかと思っていた。リンクありがとう。 – fuzzygoat

+0

+1この回答は私の答えよりも簡潔ですので、私はこれを支持して私を削除します。 –

+0

@fuzzygoat問題なし、願っています。 – kevboh

1

objectForKey:を使用して検討すべきです。 あなたが他の何かをしたい場合は、あなたが今、この配列を使用しただけでなく、あなたが作業を行うことができ

NSArray *allValues = [returnVal allValues]; 

use-できるかもしれません。 そして、もしあなたが何か具体的なことを言いたいのなら、そのことについて言及してください。何か他の方法があるかもしれません。

もNSDictionaryのクラスとして任意のプロパティが定義されていないので、ドット表記は直接可能ではありません。

0

技術的には、あなたはこのような何かを行うことができます。

typedef id (^valueBlock)(id); 
@interface NSDictionary(dotNotationAddons) 

@property(nonatomic, readonly) valueBlock value; 

@end 

@implementation NSDictionary(dotNotationAddons) 

-(valueBlock) value 
{ 
    return [[^(id key) { 
     return [self objectForKey:key]; 
    } copy] autorelease]; 
} 

@end 

int main (int argc, const char * argv[]) 
{ 
    @autoreleasepool { 
     NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"1", @"One", @"2", @"Two", @"3", @"Three", @"4", @"Four", nil]; 

     id value = dictionary.value(@"One"); 

     NSLog(@"%@", value); 
    } 


    return 0; 
} 

それはあなたが探していたものである場合、私は知らないが、私はそれが役に立てば幸い!

+0

誰かが正直にこれを投票する理由を理解できません。それは、OPが尋ねたものに答える、どのようにドット表記で辞書にアクセスできますか?これはそれを可能にする。 –

+2

これは興味深いですが、@ fuzzygoatの質問にどのように関連していますか? – benzado

+0

@benzadoなぜなら、NSDictionaryをドット表記で使うことができるからです。 –

5

実際にはありません。

ドット表記法は、そのセレクタ名でメソッドを呼び出すという簡略化した方法です。言い換えれば、この...

NSLog(@"Hello, %@", foo.bar.name); 

...これと同じです...

NSLog(@"Hello, %@", [[foo bar] name]); 

私は「同じ」と言うとき、私は、彼らが同じコードにまでコンパイルされている意味します。それはただ構文的な砂糖です。

プレーンなNSDictionaryはそのように動作しません。あなたが本当にしかし、あなたのコードでfoo.bar.nameを書くことができるようにしたい場合

NSLog(@"Hello, %@", [foo valueForKeyPath:@"bar.name"]); 

、あなたが持っていると思います:あなたは、このような特性を得るためにvalueForKeyPathを呼び出すことができますキー値コーディング、と偽のそれを並べ替えることができforwardInvocation:をオーバーライドするカスタムクラスを作成します。これにより、オブジェクトへの未知のメッセージをキャッチして、エラーをスローする以外に何か他のことを行うことができます。この場合、未知のセレクタを、それに含まれるNSDictionaryインスタンスのルックアップに変更することができます。

しかし、そうしても、それらのプロパティ名が存在することを宣言したヘッダーファイルを作成しない限り、コンパイラはおそらく警告を生成します。

3

NSDictionaryにはobjectForKey:などの方法でアクセスする必要があります。しかし、NSDictionaryへのドット記法アクセスを許可することは可能であり、学習目的のために、これは誰かにとって興味深いかもしれない。たとえば、AFNetworkingを使用して大きなJSON辞書を取得している場合でも、このメソッドを使用するとコードのアクセスと可読性が向上します。

これは私のソリューションです:

DictionaryProperties.h:(クラスはプロパティへのアクセスのためのNSDictionaryのをラップ)

@interface DictionaryProperties : NSObject{ 
    NSMutableDictionary* _backingDict; 
} 

@property (nonatomic, strong) NSMutableDictionary* backingDict; 

+ (DictionaryProperties*) allocWithDictionary:(NSDictionary*)dict; 

@end 

DictionaryProperties.m:

#import "DictionaryProperties.h" 

@implementation DictionaryProperties 

@synthesize backingDict = _backingDict; 

- (id) initWithDictionary:(NSDictionary*)dict { 
    if (self) { 
     if ([dict isKindOfClass:[NSMutableDictionary class]]) { 
      self.backingDict = (id)dict; 
     } else { 
      self.backingDict = [[NSMutableDictionary alloc] initWithDictionary:dict]; 
     } 
    } 
    return self; 
} 
+ (DictionaryProperties*) allocWithDictionary:(NSDictionary*)dict { 
    return [[DictionaryProperties alloc] initWithDictionary:dict]; 
} 


- (void)forwardInvocation:(NSInvocation *)invocation 
{ 
    NSString* key = NSStringFromSelector(invocation.selector); 
    invocation.selector = @selector(objectForKey:); 
    [invocation setArgument:&key atIndex:2]; 

    if ([self.backingDict objectForKey:key]) { 
     [invocation invokeWithTarget:self.backingDict]; 
    } else { 
     [self doesNotRecognizeSelector:invocation.selector]; 
    } 
} 

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{ 
    return [self.backingDict methodSignatureForSelector:@selector(objectForKey:)]; 

} 
@end 

ExampleDictContent.h:(クラス辞書の中に何があるかを宣言する)

#import "DictionaryProperties.h" 

@interface ExampleDictContent : DictionaryProperties 

@property (strong, nonatomic) NSString* someData; 
@property (strong, nonatomic) NSString* someOtherData; 

@end 

@implementation ExampleDictContent 
@end 

使用方法:(辞書のシンプルな宣言、ラッパーや財産へのアクセスの割り当て)

#import "ExampleDictContent.h" 

NSDictionary* d = [NSDictionary dictionaryWithObjects:NSArray arrayWithObjects:@"someData content", @"someOtherData content", nil 
               forKeys:NSArray arrayWithObjects:@"someData", @"someOtherData", nil]; 

ExampleDictContent* dictWProps = [ExampleDictContent allocWithDictionary:d]; 

NSLog(dictWProps.someData); 
NSLog(dictWProps.someData); 

これが印刷されます:NSDictionaryにアクセスするためのファサードとして

someData content 
someOtherData content 

そこで、基本的DictionaryProperties作品を。 メソッド呼び出しを辞書のgetObjectForKey:コールに変換するには、forwardInvocationを使用します。私が気に入っているのは、辞書の自動補完が可能で、アクセスするキー(ExampleDictContent.hファイル)を明示的に宣言することもできます。このソリューションはプロパティへの書き込みアクセスを許可していませんが、以下のリンクに示すように追加できます。

この解決方法の一部は、karstenlitsche's solutionからインスピレーションを受けています。主な違いは、このソリューションはカテゴリの代わりにサブクラスに基づいていることです。

+0

[ダウンロード可能な\ [h | m \]ファイル](https://gist.github.com/warpling/829e93a1357e9ef7f282):) – Warpling

関連する問題