例如我有这些类:
现在,我有一个实例化的对象“buttonA”,它具有MyGradientButton类的特性。但是,以后可以将“buttonA”类更改为RedGradientButton并获取这个将按钮变为红色的新类特征吗?
如果可能的话,请告诉我。谢谢
答案 0 :(得分:3)
不,你不能在创建后改变类的类型。[1]
最佳方法通常是创建克隆方法。在这种情况下,类变量通常是您发送的对象。
此表单的一个常见示例是:[NSString stringWithString:s]
针对[NSMutableString stringWithString:s];
。
因为您正在处理视图,所以通常更容易定义内部类型并使用对象组合。因此,您不会拥有RedGradientButton
类型,而是拥有(例如)MyGradientButton
成员的characteristics
。然后你可以创建多个特征类型(如果子类化确实是一个很好的设计)。
[1]你可以,但不 ......如果有人告诉你如何实现它。原因是:这是不安全的,一种方法正在消失。虽然您可以设置更新方法的类,但这样做不会修改对象的其他方面。显而易见的情况是,您的对象不会被调整大小或更新以反映成员布局的任何差异,这意味着当您发送消息对象并且它访问子类中存在的成员而不是超类时,您的方法的实现将读取或写入无效的内存(这是未定义的行为)。即使它似乎有效,或者你已经动态地证明或完成了所有事情以确保它是安全的,现代运行时使用非脆弱对象ABI - 基类所需的内存可以自由地从一个版本更改为另一个版本。这样的设计在调整大小时会泄露其他错误(泄漏,无法引用的内存,或者对另一个类的数据进行内存'初始化 - 类型转换')。因此,即使您克服了分配大小的问题,您仍然需要设计一种方法来执行部分释放和部分初始化实例,使对象处于可用状态 - 非常复杂。
答案 1 :(得分:2)
回答的答案是:“你可以”。 更明智的答案是:“除非你非常清楚自己在做什么,否则你不应该这样做,因此可以证明自己是否这样做是个好主意”。
如果我是你,那么我会为RedGradientButtion
+(instancetype) redGradientButtonWithMyGradientButton:(MyGradientButton*)myGradientButton;
然后,此方法可以实现新的RedGradientButton
对象,并复制myGradientButton
的所有相关特征。然后,如果您认为这是一个好主意,它可以获取myGradientButtons
'超级视图,将其从超级视图中删除并添加新的RedGradientButton
对象而不是它。
当然,这会使对myGradientButton
的所有引用都引用一个未使用的(但仍然有效的ARC)Button对象。你必须更新它们。
您说RedGradientButton
继承自MyGradientButton
。这意味着所有使用MyGradientButton
的类应该继续运行良好 - 一旦引用已经更新了。