0

保存したモデルにクラス WidgetClass の 2 つのオブジェクトがあります。アプリが終了するたびに保存され、起動するたびに再読み込みされます。モデルを更新して、そのうちの 1 つを WidgetSubclass オブジェクトにしたいと考えています。WidgetSubclass は WidgetClass のサブクラスになります。

WidgetClass にはかなり多くの ivar があります。WidgetSubclass はほとんどまたはまったく追加しません。

更新を行う最も効率的な方法は何ですか? コアデータは使用していません。

4

1 に答える 1

1

いくつかのこと。

サブクラスがスーパークラスに 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.
 }
于 2011-08-14T03:58:02.040 に答える