在 Objective-C 中,为啥在分配给指定类型的变量时需要强制转换?

Posted

技术标签:

【中文标题】在 Objective-C 中,为啥在分配给指定类型的变量时需要强制转换?【英文标题】:In Objective-C, why is casting needed when assigning to a variable whose type is specified?在 Objective-C 中,为什么在分配给指定类型的变量时需要强制转换? 【发布时间】:2013-02-20 10:14:40 【问题描述】:

这种类型转换的使用出现了很多,例如在按钮点击动作中:

UIButton *button = (UIButton *)sender;

我的问题是为什么需要显式强制转换“(UIButton *)”。将“sender”的值分配给变量“button”不是已经有效地将其转换为指向 UIButton 的指针吗?

【问题讨论】:

【参考方案1】:

它告诉编译器你知道你在做什么:“我知道sender技术上不是UIButon*,但我保证它总是在运行时。 "

【讨论】:

【参考方案2】:

正如斯蒂芬所说,这并不是必需的。

但这是一个风格和良好商业惯例的问题。

顺便说一句,当您省略它时,您会收到警告,而不是错误。 只是为了摆脱警告,你可以简单地做:

someObject = (id) anotherObject;

这适用于对任何类的任何对象的引用。您会看到几乎没有任何铸造实际完成。 您总是可以在不强制转换的情况下分配给超类:

objectOfAClass = objectOfSubclassOfA;

底线是,它通过强迫您思考一下您实际在做什么,从而帮助您避免错误。

【讨论】:

到目前为止所有很好的答案,但我选择这个是因为编译器警告的详细信息。重申一下:分配给超类(不进行强制转换)会产生 no 警告;分配给子类(不进行强制转换)确实会生成警告。例如UILabel *label; UIView *view = label;(无警告); UIView *view; UILabel *label = view;(警告)。【参考方案3】:

在objective-c中,写动作方法是很常见的,比如

- (void)didAction:(id)sender

这个方法可以被任何对象调用(例如UIButton、UIControl等),并且期望设置发送者自己。

任何对象都是一个 id。因此,在该方法中,您有一个 id 类型的变量。如果您确定它是一个按钮,那么您可以转换为 UIButton。

另一种方法是,如果您确定该方法将仅由 UIButton 实例调用,那么您可以将您的操作方法更改为

- (void)didAction:(UIButton *)senderButton

如果这样做,则不需要投射。

请注意,对于您负责的此类铸件,没有任何问题。如果您不确定,您可以随时检查对象的类别

- (BOOL)isKindOfClass:(Class)aClass

方法。

【讨论】:

以上是关于在 Objective-C 中,为啥在分配给指定类型的变量时需要强制转换?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Objective-C中将孩子分配给父母?

为啥 Objective-C 对象必须动态分配?

为啥 Objective-C 中的头文件顶部有 import 和 class 语句?

为啥 Typescript 允许将“任何”对象类型分配给类对象?

NSStringto类成员分配崩溃

为啥在objective-c中使用@class [重复]