Objective-C: NSMutableArray returns 意外类型的未转换元素
Objective-C: Uncast element of NSMutableArray returns unexpected type
如果我无法理解以下内容。考虑以下代码:
UIImage *image = [[UIImage alloc] initWithContentsOfFile:@"car.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:imageView];
UIImage *image2 = [imageView image];
UIImage *image3 = [[array objectAtIndex:0] image];
UIImage *image4 = [(UIImageView *) [array objectAtIndex:0] image];
image2 和 image4 的指令按预期工作。另一方面,带有 image3 的行显示了一个问题,
Incompatible pointer types initializing 'UIImage *' with an expression
of type 'CIImage *'
我知道不对从 NSMutableArray
检索到的对象进行类型转换可能会导致问题。但是,我很难理解为什么编译器会认为这个表达式是 CIImage
.
类型
如果这个问题被更笼统地问过,我很抱歉,我找不到...
让我们把它分开:
UIImage *image3 = [[array objectAtIndex:0] image];
只看这部分:
[array objectAtIndex:0]
Objective-C 没有此方法调用返回的对象的类型信息,因此它将其类型化为 id
。现在您要求将 image
消息发送到 id
。但是 id
不是类型对象。这是什么Objective-C?
基本上,它必须猜测你发送的是什么消息。因此,它会查看其已知的 image
方法库,然后只选择一个。它知道六种这样的方法:
你说的是第四个。但是碰巧编译器选择了第一个,returns 一个 CIImage。所以按照你的标准,它猜到了 "wrong"。但是你让它猜了,它不得不猜 something.
这正是您上一个示例中的转换所解决的问题:
UIImage *image4 = [(UIImageView *) [array objectAtIndex:0] image];
所以,道德:不要做你在 image3
行中所做的事情。执行您在 image4
行中执行的操作!你有编译器没有的类型信息:告诉编译器你知道什么。
(请注意,您编写代码的方式实际上没有造成任何伤害。编译器警告只是一个警告。实际上,当 image
消息发送到 UIImageView 时,一个UIImage 将被返回,一切都会好起来的。但是编译器警告你它不知道这一点。通过不强制转换,你已经放弃了所有静态类型并迫使编译器放手。编译器不知道会发生什么,因此它会警告您必须在运行时 解决这个问题。当您进行转换时,您会在编译时 解决问题。 )
如果我无法理解以下内容。考虑以下代码:
UIImage *image = [[UIImage alloc] initWithContentsOfFile:@"car.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:imageView];
UIImage *image2 = [imageView image];
UIImage *image3 = [[array objectAtIndex:0] image];
UIImage *image4 = [(UIImageView *) [array objectAtIndex:0] image];
image2 和 image4 的指令按预期工作。另一方面,带有 image3 的行显示了一个问题,
Incompatible pointer types initializing 'UIImage *' with an expression of type 'CIImage *'
我知道不对从 NSMutableArray
检索到的对象进行类型转换可能会导致问题。但是,我很难理解为什么编译器会认为这个表达式是 CIImage
.
如果这个问题被更笼统地问过,我很抱歉,我找不到...
让我们把它分开:
UIImage *image3 = [[array objectAtIndex:0] image];
只看这部分:
[array objectAtIndex:0]
Objective-C 没有此方法调用返回的对象的类型信息,因此它将其类型化为 id
。现在您要求将 image
消息发送到 id
。但是 id
不是类型对象。这是什么Objective-C?
基本上,它必须猜测你发送的是什么消息。因此,它会查看其已知的 image
方法库,然后只选择一个。它知道六种这样的方法:
你说的是第四个。但是碰巧编译器选择了第一个,returns 一个 CIImage。所以按照你的标准,它猜到了 "wrong"。但是你让它猜了,它不得不猜 something.
这正是您上一个示例中的转换所解决的问题:
UIImage *image4 = [(UIImageView *) [array objectAtIndex:0] image];
所以,道德:不要做你在 image3
行中所做的事情。执行您在 image4
行中执行的操作!你有编译器没有的类型信息:告诉编译器你知道什么。
(请注意,您编写代码的方式实际上没有造成任何伤害。编译器警告只是一个警告。实际上,当 image
消息发送到 UIImageView 时,一个UIImage 将被返回,一切都会好起来的。但是编译器警告你它不知道这一点。通过不强制转换,你已经放弃了所有静态类型并迫使编译器放手。编译器不知道会发生什么,因此它会警告您必须在运行时 解决这个问题。当您进行转换时,您会在编译时 解决问题。 )