NSNull在NSMutableArray中

时间:2012-09-03 17:49:24

标签: objective-c cocoa nsmutablearray

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>对象始终保留在索引1处,而不是递增到3,5,依此类推。我想知道为什么会这样,以及如何解决它。

2 个答案:

答案 0 :(得分:4)

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

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

indexOfObject:方法找到obj等于数组中项目的最低索引。由于[NSNull null]总是为您提供相同的对象(它是单身),当循环中的objNSNull时,indexOfObject:将始终停止在1处搜索。

for - in循环将始终按顺序遍历您的数组,因此您只需保留一个计数器即可打印当前索引:

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);。这将是有序的,所以除非你真的需要附加索引,否则我建议。

答案 1 :(得分:1)

Josh Caswell的回答是正确的,但另一种方法可能是使用block-based enumeration,因为您将获得当前索引和对象。

[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>

这种方式的好处是,您可以通过突变阻塞获得安全快速的枚举,同时您还可以获得没有其他(可能是错误的)查找的索引。

来自docs

  

对于NSArray枚举,index参数对并发枚举很有用。如果没有此参数,访问索引的唯一方法是使用indexOfObject: