【问题标题】: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 的指针吗?

【问题讨论】:

    标签: objective-c


    【解决方案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
      

      方法。

      【讨论】:

        猜你喜欢
        • 2021-05-08
        • 2012-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多