Objective-C类型推断

时间:2010-01-16 08:06:42

标签: objective-c types inference

好吧,我有一种感觉,你们可以快速指出为什么我对此感到困惑,但我有一个问题,为什么以下不会导致编译器错误或警告:< / p>

NSString * intValue = [ NSString stringWithFormat:@"int = %i", [ [ self.selectedObject valueForKey:name ] integerValue ] ];

selectedObjectNSObject,而name恰好是@property类型int的名称。

令我困惑的是为什么编译器完全愿意假设[ self.selectedObject valueForKey:name ]的返回结果是NSNumber *类型(没有对其进行类型转换),以便通过调用{{来链接消息1}}。

显然,KVC将非对象“数字”类型包装到integerValue中,但编译器无法知道NSNumber在这种特殊情况下会返回-valueForKey:

为什么这不会导致编译器警告“NSNumber *可能无法响应'id'”?

2 个答案:

答案 0 :(得分:10)

我希望我做对了:这是因为id是“特殊的”。 id类型的对象可以发送您想要的任何消息,编译器不会进行检查,所有内容都将在运行时进行检查。或者,换句话说,id类型是Objective-C的“动态类型”部分,而所有其他类型(如NSObject)是“静态类型”部分。

通过这种方式,您可以选择要使用静态类型的位置以及要使用动态类型的位置。做这样的事情是完全合法的:

id str1 = @"Hello";
id str2 = [str1 stringByAppendingString:@", world"];

但通常你将字符串“紧紧地”键入为NSString,因为你可以方便地进行编译时静态类型检查,并且只能采用动态类型,而静态类型会阻碍它,就像在valueForKey情况下。

答案 1 :(得分:4)

时间过去了,由于有了__auto_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'"

much more

实际上,我非常喜欢这个,所以为了方便起见,我把它做成了一个豆荚。

pod 'SwiftyObjC'