0

allItems是一个NSMutableArray,当用户单击加号按钮时,该方法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>对象始终保持在索引 1 处,而不是递增到 3、5 等。我想知道为什么会这样以及如何解决它。

4

2 回答 2

4

您没有显示日志记录的代码,但是,根据结果,我会说您正在执行以下操作:

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

该方法查找与数组中的项目相等indexOfObject:的最低索引。obj由于[NSNull null]总是给你相同的对象(它是一个单例),当obj在循环中时NSNullindexOfObject:总是会在 1 处停止搜索。

-循环将始终按顺序遍历您的数组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 回答