Cocoa——在应用程序更新中更改对象的类?

发布于 2024-10-09 09:57:19 字数 226 浏览 7 评论 0原文

我的存储模型中有两个 WidgetClass 类的对象。每次应用程序退出时都会保存它们,并在每次启动时重新加载。我想更新我的模型以使其中之一成为 WidgetSubclass 对象。 WidgetSubclass 将是 WidgetClass 的子类。

WidgetClass 有相当多的 ivars。 WidgetSubclass 将添加很少或不添加。

完成更新最有效的方法是什么?我没有使用核心数据。

I have two objects of class WidgetClass in my stored model. They are saved each time the app exits and reloaded each time it starts. I want to update my model to make one of them a WidgetSubclass object. WidgetSubclass will be a subclass of WidgetClass.

WidgetClass has quite a lot of ivars. WidgetSubclass will add few or none.

What is the most efficient way to accomplish the update? I am not using core data.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

她说她爱他 2024-10-16 09:57:19

有几件事。

如果子类没有向超类添加任何 ivars,您实际上可以避免以下情况:

WidgetSubclass* widget = (WidgetSubclass*)[[WidgetClass alloc]initWithCoder: someCoder];
Class object_setClass(widget, [WidgetSubclass class]);

存在运行时中的更改可能会破坏上述代码的风险。所以这里有一个更安全的方法:

Foo.m:

-(void) copyIvarsTo: (Foo*) foo {
    [super copyIvarsTo: foo];
    foo.ivar1 = [self.objectIvar1 copy];
    foo.ivar2 = [self.objectIvar2 copy];
    foo.floatIvar = self.floatIvar;
    // etc.  Method works fine if foo is actually a member of a subclass.
 }

 -(Foo*) copy {
    Foo* clone = [[self class]alloc];
    [self copyIvarsTo: clone];
    return clone;
 }

现在我可以拥有以下 NSObject 类别方法:

 -(NSObject*) wj_copyWithSubclass: (Class) subclass {
    if (![self respondsToSelector: @selector(copyIvarsTo:)])
        return nil;
    NSAssert([subclass isSubclassOfClass: [self class]], @"call copyWithSubclass only on subclasses");
    NSObject* clone = [subclass alloc];
    [self copyIvarsTo: clone];
    return clone; // at this point, clone has copied all the ivars that are members of the receiver's class.  Other ivars have their default values.  Calling code needs to handle that.
 }

Couple of things.

If the subclass does not add any ivars to the superclass, you can actually get away with the following:

WidgetSubclass* widget = (WidgetSubclass*)[[WidgetClass alloc]initWithCoder: someCoder];
Class object_setClass(widget, [WidgetSubclass class]);

There is some risk that changes in the runtime could break the above code. So here is a safer way:

Foo.m:

-(void) copyIvarsTo: (Foo*) foo {
    [super copyIvarsTo: foo];
    foo.ivar1 = [self.objectIvar1 copy];
    foo.ivar2 = [self.objectIvar2 copy];
    foo.floatIvar = self.floatIvar;
    // etc.  Method works fine if foo is actually a member of a subclass.
 }

 -(Foo*) copy {
    Foo* clone = [[self class]alloc];
    [self copyIvarsTo: clone];
    return clone;
 }

Now I can have the following NSObject category method:

 -(NSObject*) wj_copyWithSubclass: (Class) subclass {
    if (![self respondsToSelector: @selector(copyIvarsTo:)])
        return nil;
    NSAssert([subclass isSubclassOfClass: [self class]], @"call copyWithSubclass only on subclasses");
    NSObject* clone = [subclass alloc];
    [self copyIvarsTo: clone];
    return clone; // at this point, clone has copied all the ivars that are members of the receiver's class.  Other ivars have their default values.  Calling code needs to handle that.
 }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文