在 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 中的头文件顶部有 import 和 class 语句?