2

例如,我有这些课程:

  1. 我的渐变按钮.h/.m
  2. RedGradientButton.h/.m(继承背景颜色为红色的 MyGradientButton 类)

现在,我有一个具有 MyGradientButton 类特征的实例化对象“buttonA”。但是,以后是否可以将“buttonA”类更改为 RedGradientButton 并获得这个新的类特性,这将使按钮变为红色?

如果可能的话,让我知道怎么做。谢谢

4

2 回答 2

3

不,您不能在创建类后更改其类型。[1]

最好的方法通常是创建一个克隆的方法。在这种情况下,类变量通常是您发送消息的对象。

这种形式的一个常见例子是:[NSString stringWithString:s]反对[NSMutableString stringWithString:s];

因为您正在处理一个视图,所以通常更容易定义一个内部类型并使用对象组合。所以你不会有一个RedGradientButton类型,而是一个MyGradientButton有(例如)characteristics成员的类型。然后您可以创建多个特征类型(如果子类化确实是一个好的设计)。


[1] 你可以,但不要…如果有人告诉你如何实现它。原因:这是不安全的,一种方法正在消失。尽管您可以设置会更新方法的类,但这样做不会修改对象的其他方面。明显的情况是您的对象不会调整大小或更新以反映成员布局中的任何差异,这意味着当您向对象发送消息并访问存在于子类而不是超类中的成员时,您的方法的实现将读取或写入无效的内存(这是未定义的行为)。即使它看起来有效,或者您已经动态地证明或尽一切可能确保它是安全的,现代运行时使用非易碎对象 ABI - 您的基类所需的内存可以自由地从一个版本更改为另一个版本。这样的设计在调整大小时容易出现其他错误(泄漏、无法引用的内存或内存“在类型转换时初始化”到另一个类的数据)。因此,即使您克服了分配大小的问题,您仍然需要设计一种方法来执行实例的部分解除分配和部分初始化,以使对象处于可用状态 - 相当复杂。

于 2013-10-01T06:36:33.137 回答
2

学术界的答案是:“是的,你可以”。更聪明的答案是:“不,你不应该这样做,除非你非常了解自己在做什么,因此可以证明自己这样做是否是一个好主意”。

如果我是你,那么我会为之RedGradientButtion类创建一个新的工厂方法+(instancetype) redGradientButtonWithMyGradientButton:(MyGradientButton*)myGradientButton;

然后,此方法可以实例化一个新RedGradientButton对象并复制myGradientButton. 然后,如果您认为这是一个好主意,它可以获取myGradientButtons' 超级视图,将其从其超级视图中删除并添加新RedGradientButton对象而不是它。当然,这将使所有引用都myGradientButton指向未使用(但 ARC 仍然有效)的 Button 对象。您将不得不更新它们。

你说RedGradientButton继承自MyGradientButton. 这意味着所有使用的类都MyGradientButton应该继续正常工作——当然,一旦更新了引用。

于 2013-10-01T07:06:47.647 回答