2

iPhoneアプリのキー値コーディングを使用して配列にデータを入力する「正しい」方法を見つけようとしています。私はうまくいくものを思いつきましたが、それはかなりハックです。基本的に、私は XML ドキュメントを一連のコード生成モデルに解析しています。XML が次の形式であるとします。

<foo>
    <bar>
        <item name="baz" />
        <item name="bog" />
    </bar>
</foo>

Bar 要素を表す生成されたオブジェクトでは、サブノード用に定義された NSMutableArray があります。

@interface Bar : NSObject {
    NSMutableArray *item;
}
@end

したがって、デフォルトでは、Bar のインスタンスで setValue:forKey: を呼び出すと、NSMutableArray のインスタンスが Item オブジェクトの単一のインスタンスで上書きされます。これを機能させるために私が現在行っていることは、ハッキーになるところです。配列インスタンス変数の名前を別のものに変更しました。名前の複数形を考えてみましょう:

@interface Bar : NSObject {
    NSMutableArray *items;
}
@end

これにより、setValue:forKey: のデフォルトのアクセサーが失われます。次に、このメソッドを Bar 実装に追加しました。

- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
    if([key isEqualToString:@"item"]) {
        if(items == nil) {
            items = [[NSMutableArray alloc] init];
            [items retain];         
        }
        [items addObject:value];
    }
}

そして、すべてが機能します!しかし、これを行うためのより良い方法があるに違いないと確信しています! Key-Value Coding Programming Guide を読みましたが、配列アクセサーがどのように機能するかがよくわからないため、何かが欠けているに違いありません。countOf: と objectInAtIndex: を KVC プログラミング ガイドが示すように実装しようとしましたが、それでも NSMutableArray が Item タイプのインスタンスで上書きされます。

4

4 に答える 4

2

Martin が示唆しているように、配列を直接観察して、アイテムがいつ追加または削除されたかを確認することはできません。代わりに、これは Bar オブジェクトの「to-many」属性と見なされ、KVO アサーションを自分で作成する必要があります。バーのアイテムを追加および削除するには、次のようなことができます。

@interface Bar : NSObject
{
    NSMutableArray *items;
}
-(void)addItem:(id)item;
-(void)removeItem:(id)item;
@end

@implementation Bar
-(id)init
{
    if( (self = [super init]) ) {
        items = [[NSMutableArray alloc] init];
    }
    return self;
}

-(void)addItem:(id)item
{
    NSParameterAssert(item);
    NSIndexSet *iset = [NSIndexSet indexSetWithIndex:[items count]];
    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:iset forKey:@"items"];
    [items addObject:item];
    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:iset forKey:@"items"];
}

-(void)removeItem:(id)item
{
    NSParameterAssert(item);
    NSIndexSet *iset = [NSIndexSet indexSetWithIndex:[items indexForObject:item]];
    [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:iset forKey:@"items"];
    [items removeObject:item];
    [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:iset forKey:@"items"];
}
@end

アイテムを直接設定/置換できるようにしたい場合は、自分でそれを行う方法を考え出す必要があります。普段ならこういうNSArrayControllerのは と をお勧めしますが、iPhone を使っているので、基本的に自分でこの機能を作る必要があります。

于 2009-01-30T02:43:46.913 に答える
0

さて、あなたがそれについて行くことができる2つの方法があります:

  1. アイテムを渡す Bar クラスに「Add Item」メソッドを追加します
  2. KVCを実行するときは、アイテムの配列全体を渡していることを確認してください

KVC を使用して配列に項目を追加する方法があるとは思いません。

于 2009-01-30T02:05:18.050 に答える
0

呼び出すだけで十分でvalueForKey:@"item"あり、結果は可変になります。したがって、次のように言えます。

NSMutableArray* m = [theBar valueForKey:@"item"];
[item addObject: value];

ファサード (変更可能なインスタンス変数がないキー) を実装していない限り、これらの他のメソッドは必要ありません。

于 2010-06-09T18:07:12.770 に答える