目标C中的类型转换失败

时间:2016-05-05 08:40:32

标签: ios objective-c casting

此处的类型转换成功

id object = [NSMutableArray array];
NSURLConnection *urlCon = (NSURLConnection*)object;

if ([urlCon isKindOfClass:[NSURLConnection class]])
    NSLog(@"urlCon is NSURLConnection");
else if ([urlCon isKindOfClass:[NSMutableArray class]])
    NSLog(@"urlCon is NSMutableArray"); // this is called

实际上,因为'object'的类型为NSMutableArray,所以NSURLConnection的类型转换会失败。但它是成功的,urlCon仍然指向NSMutableArray,那么TypeCasting的用途是什么?

2 个答案:

答案 0 :(得分:7)

有两个不同的问题:一个是变量的类型。另一个是底层对象的类型。

在Objective-C中,对象指针的转换不会改变底层对象的内容。在Objective-C中进行投射不会“成功”或“失败”。它只是告诉编译器允许您将变量视为实际指向已转换类型的对象。通常在以下情况下执行此操作:(a)您对编译器无法合理知道的基础对象有一些了解,并且(b)您希望能够在没有编译器抱怨的情况下调用某个类的某个特定方法。显然,情况并非如此,您已将urlCon变量转换为期望objectNSURLConnection,而不是isKindOfClass

但是isKindOfClass是一个运行时检查,实际上是查看底层对象的类型,并不关心变量的类型。

一个常见模式将使用NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if ([response isKindOfClass:[NSHTTPURLResponse class]]) { // check to see if response is `NSHTTPURLResponse` NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; // if so, cast `NSURLResponse` to `NSHTTPURLResponse` NSInteger statusCode = httpResponse.statusCode; // now you can use `statusCode` property of `NSHTTPURLResponse` if (statusCode != 200) { // Non 200 status code ... so handle HTTP error accordingly here } } // carry on }]; [task resume]; 来确定某个对象是否属于某个特定类,如果是,则将其转换为该特定类型,以便您可以使用该方法和/或属性没有来自编译器的警告的类。

因此,在处理网络请求时,您经常会看到这种模式:

isKindOfClass

这种模式有一些稍微简单的再现,但希望它说明了这个想法:当你知道(或以编程方式确认)某些关于所指向的对象类型的东西时,你就会进行转换,而你只是想得到编译器在同一页面上,以便您现在可以使用它。您可以使用<ce:para view="all">Web and grid services <ce:cross-refs refid="BIB10 BIB11">[10,11]</ce:cross-refs>, where they can provide rich service descriptions that can help in locating suitable services.</ce:para> 作为运行时检查来确认它确实是那种类型,但是强制转换可以让您使用它。

答案 1 :(得分:2)

您所经历的是完全预期的行为。

将类型为X的对象转换为类型Y,更改对象,它只是强制类型为X的对象看起来像Y类型的对象,即使它是类型的X

如果您开始调用对象上的任何函数,那么您在示例中所做的事情很可能会调用很多未定义的行为,因为NSMutableArray不是NSURLConnection的子类或超类

你做的是一个C风格的演员阵容。在C中,您可以将任何两种指针类型相互转换,不需要进行任何检查来验证它。