Objective c 目的C型推理
好的,我有一种感觉,你们可以很快指出为什么我对这一点如此困惑,但我有一个问题,为什么以下内容不会导致编译器错误或警告:Objective c 目的C型推理,objective-c,types,inference,Objective C,Types,Inference,好的,我有一种感觉,你们可以很快指出为什么我对这一点如此困惑,但我有一个问题,为什么以下内容不会导致编译器错误或警告: NSString * intValue = [ NSString stringWithFormat:@"int = %i", [ [ self.selectedObject valueForKey:name ] integerValue ] ]; selectedObject是一个NSObject,而name恰好是int类型的@属性的名称 让我困惑的是,为什么编译器完全愿意假
NSString * intValue = [ NSString stringWithFormat:@"int = %i", [ [ self.selectedObject valueForKey:name ] integerValue ] ];
selectedObject
是一个NSObject
,而name
恰好是int
类型的@属性的名称
让我困惑的是,为什么编译器完全愿意假设[self.selectedobjectvalueforkey:name]
的返回结果是类型NSNumber*
(不进行类型转换),以便通过调用integerValue
链接消息
显然,KVC将非对象“number”类型包装为NSNumber
,但编译器无法知道在这种特殊情况下-valueForKey:
将返回一个NSNumber*
为什么这不会导致编译器警告“id
可能不响应“-integerValue
”?我希望我的回答是正确的:这是因为id
是“特殊的”。id
类型的对象可以发送您想要的任何消息,编译器不进行任何检查,所有内容都将在运行时检查。或者,换句话说,id
类型是Objective-C的“动态类型”部分,而所有其他类型(如NSObject
)是“静态类型”部分
通过这种方式,您可以选择在哪里使用静态类型,在哪里使用动态类型。这样做是完全合法的:
id str1 = @"Hello";
id str2 = [str1 stringByAppendingString:@", world"];
但通常您会将字符串“紧密”地键入为NSString
s,因为您可以方便地进行编译时静态类型检查,并且只在静态类型会妨碍的情况下使用动态类型,就像在valueForKey
情况下一样。时间过去了,由于\uu auto\u type
从Xcode 8开始提供。所以现在你可以做了
#define let __auto_type const
#define var __auto_type
let a = @[@"pew pew"];
var b = 2;
b = a; //compiler warning "Incompatible pointer to integer conversion assigning to 'int' from 'NSArray *__strong const'"
及
事实上,我非常喜欢这个,所以为了方便,我把它做成了一个豆荚
pod 'SwiftyObjC'
谢谢我有一种感觉,这与id
是Objective-C中的特权类型有关:)我的倾向是总是尽可能地严格地键入内容,所以我想我从未遇到过这种看似奇怪的行为。我猜这使得id
既强大又危险。我想知道,在处理id
时,是否最好通过类型转换为编译器提供一些上下文,或者如果您对id
将变成什么(就像我的示例中的情况一样)持肯定态度,则不必考虑这些上下文。经验法则是:“尽可能使用静态类型,需要时使用动态类型。”(你可以在谷歌上搜索以获取更多信息。)在这种情况下,我不会进行类型转换,这只会使表达式更难阅读。有时你必须进行类型转换以帮助编译器选择正确的方法–请参阅。感谢链接。由于方法命名发生“冲突”,我遇到了一些令人讨厌的小错误使用现有的SDK方法名称。我认为编译器对我来说太疯狂了。:)是的,我完全支持“在可能的情况下静态类型,在需要时动态类型”的理念。现在,如果Objective-C能够添加对类型化集合的支持。。。似乎更多的时候,我知道我的收藏将要储存什么。