为什么运行时允许将NSDictionary从数组中分配到NSString变量中?

时间:2014-09-01 20:00:27

标签: objective-c types variable-assignment

考虑以下代码:

NSMutableArray *array = [[NSMutableArray alloc]init];
for(int i = 0; i < 5 ; i++) 
    [array addObject:[[NSDictionary alloc]init]];
NSString *poisonedString = [array objectAtIndex:0];

在上面的代码片段中,我有一个数组,我将一些字典对象插入到这个数组中。虽然这一切都很好,但是当我从数组中获取字典对象并将其放入字符串对象时,它不会导致任何强制转换异常!程序运行顺畅,然后只有在poisonedString上进行字典操作时才会崩溃!为什么会这样?当字典对象放入poisonedString时,为什么Objective-C运行时没有看到类型不匹配并在赋值时引发异常?

3 个答案:

答案 0 :(得分:2)

简而言之,NSArray支持在其中插入任何类型的对象。如果查看文档,可以看到使用 objectAtIndex 时返回通用(id)对象:

 - (id)objectAtIndex:(NSUInteger)index

考虑到这一点,你不能指望编译器提前知道你从数组中获取对象时的类型。

答案 1 :(得分:1)

因为首先你没有投射:)我无法看到任何演员阵容,其次,欢迎来到Objective-C,这就是他们所谓的动态语言,你可以在这里阅读更多内容 https://developer.apple.com/library/mac/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/WorkingwithObjects/WorkingwithObjects.html

现在回到你的代码,数组不是通用的,所以你可以在同一个数组中添加你想要的任何类的项目,当你得到项目时,你不需要投射它,编译器信任你:D现在如果你试图发送一条消息(或者你命名它做了一些操作),它会抛出一个运行时异常,所以如果你处于你不知道它是否和&# #39;是NSString或NSDictionary,只需使用下面的代码来检查对象的类型。

if ([array[0] isKindOfClass:[NSDictionary class]]) {
    // Do whatever you want
}
else if ([array[0] isKindOfClass:[NSString class]]) {
    // Also do whatever you want
}

答案 2 :(得分:0)

在NSArray类中引用文档,表明ObjectAtIndex的返回值是id

objectAtIndex: 返回位于指定索引处的对象。

- (id)objectAtIndex:(NSUInteger)index

当指针是id时,编译器无法知道对象的类型。在执行时而不是在编译时进行转储是正常的。