简体   繁体   English

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

[英]Objective-C: Force a class to be a subclass of other

B is subclass of A. C is a subclass of A. When i create ci do if((self = [NSKeyedUnarchiver unarchiveObjectWithFile:…])) { } inside the .m in C. B是A的子类。C是A的子类。当我创建ci时,请在C中的.m内执行if((self = [NSKeyedUnarchiver unarchiveObjectWithFile:…])) { }

So despite i set the the superclass in Ch to be B (which is what i want), when i create the C object from unarchiveObjectWithFile: since this object is subclass of A, i can't force it to be subclass of B. (Hard to explain sorry). 因此,尽管我将Ch中的超类设置为B(这就是我想要的),但是当我从unarchiveObjectWithFile:创建C对象时unarchiveObjectWithFile:由于此对象是A的子类,所以我不能强迫它成为B的子类。很难解释抱歉。

Is there any workaround ??? 有什么解决方法吗?

In other words: when i unarchiveObjectWithFile:… an object that pertains to a class A, and i have another class B that is subclass of A, can the unarchiveObjectWithFile: be a subclass of B? 换句话说:当我unarchiveObjectWithFile:…属于一个类A的对象,而我又有另一个类B是A的子类时, unarchiveObjectWithFile:可以成为B的子类吗? (wich is allowed since B is subclass of a) (因为B是a的子类,所以允许夹心)

If I understand correctly: No. 如果我理解正确:否。

If you archive an instance of B then when you unarchive it you get an instance of B , likewise for instances of A and C . 如果归档B的实例,则在取消归档时会得到B的实例,对于AC实例也是如此。

However, in non-technical language, a subclass is everything its superclass is plus some extra bits. 但是,用非技术语言来说,子类是其超类的全部内容, 外加一些额外的位。 You can't[*] take an instance of a superclass, created directly or from unarchiving, and make it into an instance of one of its subclasses - the "extra bits" are not there. 您不能[*]直接或通过存档创建超类的实例,并使其成为其子类之一的实例-“多余的位”不存在。

HTH 高温超导

[*] Before someone comments: Yes, this is not absolutely true in all situations, but you are entering obscure, highly specialised, and dangerous waters. [*]在有人评论之前:是的,并非在所有情况下都绝对正确,但是您正在进入晦涩,高度专业和危险的水域。 Don't go there. 不要去那

Addendum 附录

Seems you might be in the category where changing the class of an object is safe: you should be able to change the class of an instance to a subclass provided the subclass adds no instance variables or properties. 似乎您属于安全更改类别的类别:您应该能够将实例的类别更改为子类, 前提是该子类未添加任何实例变量或属性。 To do this you can use the Objective-C runtime functions : 为此,您可以使用Objective-C运行时函数

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

You can also use the unarchiving classes to set the class. 您也可以使用取消归档的类来设置类。

Do not do this casually. 不要随便这样做。 Consider alternatives, but sometimes it is an appropriate solution. 考虑替代方案,但有时它是一个合适的解决方案。

The unarchiver wants to create the same type of class that was perviously archived, and that's generally what you want too. 取消存档的人想要创建以前存档过的相同类型的类,这通常也是您想要的。

You could look at using setClass:forClassName: to change the class that will be unarchived, but you stand a good chance of ruining everything sooner or later... 您可以看看使用setClass:forClassName:来更改将要取消归档的类,但是您早晚有可能毁掉所有内容。


Based on the particle comment: 基于粒子注释:

Another option is to take the superclass instance and 'wrap' it in your subclass instance. 另一种选择是获取超类实例并将其“包装”在您的子类实例中。 So, you can archive and unarchive your subclass instance and it will contain the superclass instance. 因此,您可以存档和取消存档您的子类实例,它将包含超类实例。 Any method that your subclass doesn't directly respond to you can forward on to the superclass instance. 您的子类没有直接响应的任何方法都可以转发到超类实例。

In this way you have 2 objects but you aren't tampering with anything or relying on implementation details of classes that you don't own. 这样,您就有2个对象,但是您不会篡改任何东西,也不会依赖于您不拥有的类的实现细节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM