Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/111.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 类型转换在目标C中失败_Ios_Objective C_Casting - Fatal编程技术网

Ios 类型转换在目标C中失败

Ios 类型转换在目标C中失败,ios,objective-c,casting,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]])

这里的类型转换成功

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,那么类型转换有什么用呢?

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

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

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


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

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

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

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


你做的是C风格的演员。在C语言中,您可以将任意两种指针类型强制转换为另一种类型,不需要进行任何检查。

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

在Objective-C中,对象指针的转换不会改变底层对象的内容。而在Objective-C中的角色扮演既不成功也不失败。它只是告诉编译器允许您将变量视为实际指向铸造类型的对象。通常,在这样的情况下,a您对底层对象有一些编译器无法合理了解的知识,b您希望能够调用某个类的某个特定方法,而无需编译器对此抱怨。显然,这里的情况并非如此,您已将urlCon变量强制转换为预期对象为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作为运行时检查,以确认它确实是该类型,但强制转换允许您这样使用它。

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

在Objective-C中,对象指针的转换不会改变底层对象的内容。而在Objective-C中的角色扮演既不成功也不失败。它只是告诉编译器允许您将变量视为实际指向铸造类型的对象。通常,在这样的情况下,a您对底层对象有一些编译器无法合理了解的知识,b您希望能够调用某个类的某个特定方法,而无需编译器对此抱怨。显然,这里的情况并非如此,您已将urlCon变量强制转换为预期对象为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作为运行时检查,以确认它确实是该类型,但强制转换允许您这样使用它。

@Sulthan在C中,指针类型可以自由地相互强制转换,而无需任何检查。C不是C++。这本书不需要编辑
警告:NSMUTABLEARRY*arr=[NSMUTABLEARRY new];NSURLConnection*con=NSURLConnection*arr@在C语言中,指针类型可以自由地相互转换,无需任何检查。C不是C++。这在编译时没有警告:NSMUTABLEARRY*arr=[NSMUTABLEARRY new];NSURLConnection*con=NSURLConnection*arr;显然,根据苹果公司的Obj-C营销策略,这实际上是一个特性,而不是一个问题。我不确定这种行为是好事还是坏事。最后一句话的问题是,这是一种运行时工具还是编译时工具一些苹果开发人员告诉我这是编译时,所以只是想知道。我想这也是所有种类的变化,不仅仅是种类,如果我错了,请纠正我?thx:@l'l'l-isKindOfClass和isMemberOfClass是在运行时确定的,而不是在编译时确定的。事实上,它最常用于编译时无法知道对象是什么,而只能在运行时知道的情况。与你交谈的苹果工程师肯定在谈论其他事情。无论如何,我已经修改了示例,以展示运行时类测试的实际示例,用于确保后续转换是安全的;以防你想知道苹果的参考资料或者它被提到的地方。在演讲中,我知道演讲者在话题上来回跳跃是很常见的,所以我很可能在错误的背景下对其进行了解释。是的,他们谈论的是Cocoa API的快速化。Swift比Objective-C更重视类型安全。他们是对的,在语言中强制执行类型安全(即在编译时)是一个很大的改进。但是我们仍然需要像上面这样的运行时检查,您可以在Swift中使用iskindof类,is类型检查关键字或as?很显然,根据苹果公司的Obj-C营销策略,这实际上是一个特性,而不是一个问题。我不确定这样的行为是好事还是坏事。最后一句话的问题是,这是一种运行时工具还是编译时工具一些苹果开发人员告诉我这是编译时,所以只是想知道。我想这也是所有种类的变化,不仅仅是种类,如果我错了,请纠正我?thx:@l'l'l-isKindOfClass和isMemberOfClass是在运行时确定的,而不是在编译时确定的。事实上,它最常用于编译时无法知道对象是什么,而只能在运行时知道的情况。与你交谈的苹果工程师肯定在谈论其他事情。无论如何,我已经修改了示例,以展示运行时类测试的实际示例,用于确保后续转换是安全的;以防你想知道苹果的参考资料或者它被提到的地方。在演讲中,我知道演讲者在话题上来回跳跃是很常见的,所以我很可能在错误的背景下对其进行了解释。是的,他们谈论的是Cocoa API的快速化。Swift比Objective-C更重视类型安全。他们是对的,在语言中强制执行类型安全(即在编译时)是一个很大的改进。但是我们仍然需要像上面这样的运行时检查,您可以在Swift中使用iskindof类,is类型检查关键字或as?优雅地处理强制转换失败。