Objective-C:强制一个类成为其他类的子类

时间:2014-03-29 17:53:02

标签: ios objective-c nskeyedarchiver nskeyedunarchiver

B是A的子类.C是A的子类。当我创建c时,我在C中的.m内做if((self = [NSKeyedUnarchiver unarchiveObjectWithFile:…])) { }

所以尽管我将Ch中的超类设置为B(这是我想要的),当我从unarchiveObjectWithFile:创建C对象时,因为这个对象是A的子类,我不能强迫它是B的子类。(很难解释抱歉)。

有解决办法吗?

换句话说:当i unarchiveObjectWithFile:…一个属于A类的对象,并且我有另一个B类是A的子类时,unarchiveObjectWithFile:可以是B的子类吗? (由于B是a的子类,因此被允许)

2 个答案:

答案 0 :(得分:4)

如果我理解正确:不。

如果您归档B的实例,那么当您取消归档时,您会获得B的实例,同样适用于AC的实例。

但是,在非技术语言中,子类是其超类加上一些额外位的所有内容。你不能[*]获取一个超类的实例,直接创建或从unarchiving创建,并使其成为其子类之一的实例 - "额外位"不在那里。

HTH

[*]在有人评论之前:是的,这并非在所有情况下都是如此,但你正在进入模糊,高度专业化和危险的水域。不要去那里。

<强>附录

似乎您可能属于更改对象类安全的类别:您应该能够将实例的类更改为子类提供子类不添加实例变量或属性。为此,您可以使用Objective-C runtime functions

id obj = ... some instance of class A
object_setClass(obj, [B class]); // where B is a subclass of A which adds no properties or variables

您还可以使用取消归档类来设置类。

不要随便这样做。考虑替代方案,但有时它是一个合适的解决方案。

答案 1 :(得分:1)

unarchiver希望创建与之前存档的相同类型的类,这通常也是你想要的。

您可以使用setClass:forClassName:来更改未归档的课程,但您很快就会破坏所有内容......


基于粒子评论:

另一种选择是采用超类实例并包装&#39;它在你的子类实例中。因此,您可以归档和取消归档您的子类实例,它将包含超类实例。您的子类不直接响应的任何方法都可以转发到超类实例。

通过这种方式,您有2个对象,但您不会篡改任何内容或依赖您不拥有的类的实现细节。