Objective-C 类型推断

发布于 2024-08-18 14:00:59 字数 727 浏览 6 评论 0原文

好的,我有一种感觉,你们很快就能指出为什么我对此如此困惑,但我有一个问题,为什么以下内容不会导致编译器错误或警告:

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

selectedObject 是一个 NSObject,而 name 恰好是 int 类型的 @property 的名称。

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

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

为什么这不会导致编译器警告“id may not respond to '-integerValue'”?

Okay, I have a feeling that you guys'll be able to quickly point out why I'm so confused about this, but I have a question as to why the following does NOT result in a compiler error or warning:

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

selectedObject is an NSObject, and name happens to be the name of a @property of type int.

What perplexes me is why the compiler is perfectly willing to assume that the return result of [ self.selectedObject valueForKey:name ] is of type NSNumber * (without typecasting it) in order to chain the message with a call to integerValue.

Obviously, KVC wraps up non-object "number" types into NSNumber, but there's no way for the compiler to know that -valueForKey: will return an NSNumber * in this particular case.

Why doesn't this result in a compiler warning along the lines of "id may not respond to '-integerValue'"?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

彩扇题诗 2024-08-25 14:00:59

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

这样您就可以选择要在何处使用静态类型以及要在何处使用动态类型。这样做是完全合法的:

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

但通常你将字符串“紧密地”键入为 NSString,因为你可以方便地进行编译时静态类型检查,并且只在以下情况下才使用动态类型:静态的会妨碍,就像在 valueForKey 情况下一样。

I hope I got it right: This is because id is “special”. Objects of the id type can be sent any message you want, there is no checking done by the compiler and everything will be checked in runtime. Or, in other words, the id type is the “dynamic typing” part of Objective-C, whereas all the other types (like NSObject) are the “static typing” part.

This way you can choose where you want to use static typing, and where you want to use dynamic typing. It is perfectly legal to do something like this:

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

But usually you type the strings “tightly” as NSStrings, because you get the convenience of compile-time static type check, and only resort to dynamic typing where the static one would get in the way, like in the valueForKey situation.

×眷恋的温暖 2024-08-25 14:00:59

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

更多

事实上,我非常喜欢这个,所以我为了方便起见,将其作为一个 Pod。

pod 'SwiftyObjC'

Time is passed and we have better type inference now thanks to the __auto_type
available since Xcode 8. So now you can do

#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'"

and much more

In fact, I liked this so much so I made this as a pod for convenience.

pod 'SwiftyObjC'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文