通过点表示法访问NSDictionary?

fuz*_*oat 7 iphone objective-c 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.
Run Code Online (Sandbox Code Playgroud)

kev*_*boh 6

没有点语法NSDictionary,但应考虑使用objectForKey:而不是valueForKey:

objectForKey和valueForKey之间的区别?


ben*_*ado 5

不是,不是.

点表示法是使用该选择器名称调用方法的简便方法.换句话说,这......

NSLog(@"Hello, %@", foo.bar.name);
Run Code Online (Sandbox Code Playgroud)

......跟这个一样......

NSLog(@"Hello, %@", [[foo bar] name]);
Run Code Online (Sandbox Code Playgroud)

当我说"相同"时,我的意思是它们被编译成相同的代码.这只是语法糖.

一个普通的NSDictionary不会这样做.您可以使用键值编码来伪装它,它可以让您调用valueForKeyPath以获取如下属性:

NSLog(@"Hello, %@", [foo valueForKeyPath:@"bar.name"]);
Run Code Online (Sandbox Code Playgroud)

但是,如果您真的希望能够编写foo.bar.name代码,那么您必须创建一个覆盖的自定义类forwardInvocation:; 这可以让你捕获一个未知的消息给一个对象,并用它做其他事情,除了抛出一个错误.在这种情况下,您可以将未知选择器更改为它包含的NSDictionary实例上的查找.

但即使您这样做,编译器仍可能会生成警告,除非您创建了声明这些属性名称的头文件.


ben*_*der 1

不,你正在以正确的方式做这件事。在iOS世界中,往往正确的方法就是唯一的方法。:)

如果您确实想要点表示法(以及通过类型化对象获得的其他好处),则必须将字典表示形式填充到对象中。最常见的是我的界面如下所示:

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

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

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

@end
Run Code Online (Sandbox Code Playgroud)

实施应该是明确的。然后你可以

FooBar *fb = [FooBar FooBarFromDictionary:data];
NSLog(@"fb.someData = %@", fb.someData);
Run Code Online (Sandbox Code Playgroud)