将消息发送到objectForKey到NSMutableArray实例,它的工作原理!!奇怪?

时间:2011-12-08 10:37:31

标签: iphone objective-c ios nsmutablearray selector

我的程序中编写了非常糟糕的代码,只是在玩我正在学习Objective C和iOS平台。我做的是,

我已经像这样创建了NSMutableArray

placeInfo = [NSMutableArray array];

而且在我的代码后面我正在做这样的事情,基本上我在操纵Google放置api响应(JSON)。

NSDictionary *results = [responseString JSONValue];
placeInfo = [results objectForKey:@"result"];
self.phoneNumber = (NSString *)[placeInfo objectForKey:@"formatted_phone_number"]; // In this line compiler warns me that NSMutableArray might not response to this.

我检查了文档,但是在NSMutableArray中没有找到objectForKey。

  • 那可能是什么原因?为什么我的代码没有崩溃?为什么按“formatted_phone_number”键返回电话号码?

修改

在第一次回答之后,我已经编辑了我的代码并添加了这样的类型转换,但它仍然有效。

NSDictionary *results = [responseString JSONValue];
placeInfo = (NSMutableArray *)[results objectForKey:@"result"];
self.phoneNumber = (NSString *)[placeInfo objectForKey:@"formatted_phone_number"];

2 个答案:

答案 0 :(得分:3)

我从未使用Google Places API,但我猜[results objectForKey:@"result"]实际上会返回另一个字典,因此objectForKey:可以正常工作。

因为objective-c只使用指针来引用对象,所以它实际上从未被转换为NSMutableArray。另外,objective-c在编译时不知道方法是否存在,因为它具有动态特性(实际上你可以在运行时添加方法甚至整个类)。

根据编译器设置的不同,它可能会显示一条警告,指出在运行时无法找到objectForKey: ,并让它继续编译。如果您实际传递了NSDictionary,它最终会正常工作。

即使你把(NSMutableArray *)演员放在它前面,它也不会改变任何东西。这只是转换指针类型,并不会以任何方式实际更改对象。

答案 1 :(得分:2)

这样做是因为[results objectForKey:@"result"]正在返回一些不是NSMutableArray的东西。返回的内容可能是另一个NSDictionary,当然,它会响应objectForKey:要找出你所得到的内容,请在result = [placeInfo objectForKey:@"result"]之后设置断点并检查{{1} }。调试器会告诉你你正在处理什么样的对象。我敢打赌你喜欢的任何东西都是result

Objective C允许您随时向任何对象发送任何消息(称为选择器);运行时不关心特定对象是否实现给定的选择器。如果目标对象没有响应给定的选择器,它将忽略它。它不会崩溃。在这方面,它完全不同于大多数其他OOP语言,包括C ++和Java,如果您尝试调用特定类未实现的方法,则无法编译。您可以通过说NSDictionary来查明对象是否响应给定的选择器(这与使用内省以查看给定的类是否实现某种方法是一样的)。方法和消息之间的这种差异对于理解目标C至关重要。我建议在做其他任何事情之前先阅读The Objective C Programming Language

此外,Objective C的类型系统不像其他语言那样严格执行。做你在这里所做的事情是非常合法的(虽然是一个非常糟糕的主意),即声明类型为[result respondsToSelector:@selector(objectForKey:)]的指针,然后将其分配给(我猜)一个NSMutableArray。< / p>