0

allItemsNSMutableArrayユーザーがプラスボタンをクリックすると、メソッドがcreateItem呼び出されます。BNRItem偶数のインデックスごとに(クラスの) オブジェクトのみを追加しようとしているのでNSNull、奇数のインデックスのインスタンスを入れてみました。

-(BNRItem *)createItem {
    BNRItem *p = [[BNRItem alloc] init];
    if ([allItems count] == 0)
        [allItems addObject: p];
    else {
        [allItems addObject: [NSNull null]];
        [allItems addObject: p];
    }
    return p;
}

プラスボタンを3回クリックした後の出力は次のとおりです。

2012-09-03 13:20:13.876 Homepwner[718:f803] Index: 0 item: Laptop (123): Worth $60, recorded on (September)
2012-09-03 13:20:13.876 Homepwner[718:f803] Index: 1 item: <null>
2012-09-03 13:20:13.877 Homepwner[718:f803] Index: 2 item: Brush (234): Worth $14, recorded on (September)
2012-09-03 13:20:13.882 Homepwner[718:f803] Index: 1 item: <null>
2012-09-03 13:20:13.882 Homepwner[718:f803] Index: 4 item: Calculator (345): Worth $19, recorded on (September)

プラス ボタンをクリックし続けると、<null>オブジェクトは 3、5 などに増加するのではなく、常にインデックス 1 のままです。どうしてこうなったのか、どうしたら直せるのか、考えてみました。

4

2 に答える 2

4

ロギングのコードは表示されていませんが、結果に基づいて、次のようなことをしていると思います。

for( id obj in arr ){
    NSLog(@"Index: %lu item: %@", [arr indexOfObject:obj], obj);
}

このメソッドは、配列内の項目と等しいindexOfObject:最小のインデックスを見つけます。は常に同じオブジェクト (シングルトン) を提供するため、ループ内に がある場合obj、は常に1 で検索を停止します。[NSNull null]objNSNullindexOfObject:

-ループは常に配列を順番に通過するため、カウンターを保持して現在forinインデックスを出力できます。

NSUInteger idx = 0;
for( id obj in arr ){
    NSLog(@"Index: %lu item: %@", idx++, obj);
}

または「通常の」forループを使用します。

NSUInteger count = [arr count];
for( NSUInteger i = 0; i < count; i++ ){
    NSLog(@"Index: %lu item: %@", i, [arr objectAtIndex:i]);
}

description最後に、単にログに記録すると、配列はそれ自体を出力し、含まれる各項目に送信します: NSLog(@"%@", arr);. これは順番になるので、インデックスを付ける必要が本当にない限り、それをお勧めします。

于 2012-09-03T17:56:19.357 に答える
1

Josh Caswellの答えは正しいですが、現在のインデックスとオブジェクトが提供されるため、ブロックベースの列挙を使用する別の方法があります。

[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    NSLog(@"Index: %lu item:%@", idx, obj);
}];

このコード

NSMutableArray *mArray = [NSMutableArray array];

[mArray addObject:@(1)];
[mArray addObject:@(5)];
[mArray addObject:@(7)];
[mArray addObject:@(1)];
[mArray addObject:[NSNull null]];
[mArray addObject:@(10)];
[mArray addObject:[NSNull null]];

[mArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    NSLog(@"%lu %@", idx, obj);
}];

結果は次のとおりです。

Index: 0 item:1
Index: 1 item:5
Index: 2 item:7
Index: 3 item:1
Index: 4 item:<null>
Index: 5 item:10
Index: 6 item:<null>

この方法の利点は、ミューテーション ブロッキングを使用して安全で高速な列挙を行いながら、別の (おそらく誤った) ルックアップなしでインデックスを取得できることです。

ドキュメントから:

NSArray 列挙の場合、index パラメータは同時列挙に役立ちます。このパラメーターがない場合、インデックスにアクセスする唯一の方法は、indexOfObject を使用することです。

于 2012-09-03T18:46:52.307 に答える