此处的类型转换成功
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的用途是什么?
答案 0 :(得分:7)
有两个不同的问题:一个是变量的类型。另一个是底层对象的类型。
在Objective-C中,对象指针的转换不会改变底层对象的内容。在Objective-C中进行投射不会“成功”或“失败”。它只是告诉编译器允许您将变量视为实际指向已转换类型的对象。通常在以下情况下执行此操作:(a)您对编译器无法合理知道的基础对象有一些了解,并且(b)您希望能够在没有编译器抱怨的情况下调用某个类的某个特定方法。显然,情况并非如此,您已将urlCon
变量转换为期望object
为NSURLConnection
,而不是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中,您可以将任何两种指针类型相互转换,不需要进行任何检查来验证它。