NSMutableArray:添加对象“nil”?

8
我遇到了在数组末尾添加"nil"的问题,出现了"NSInvalidArgumentException"错误?
NSMutableArray *k = [NSMutableArray arrayWithCapacity:10];

for (int i=0; i<9; i++){
    [k addObject: @"blank"];
}
[k addObject: nil]; //<-- NSInvalidArgumentException

我需要在循环中逐个完成这些项目,然后添加“nil”。

谢谢

(然后我将使用此数组初始化二维数组。 问题是,如果我试图用不含“nil”的数组替换“replaceObjectAtIndex”,那么操作会失败。 如果我使用“initWithObjects:@”blank“,@”blank“,@”blank“,... nil“构建”k“,那么这将起作用。但是写1000个空格有点太多了。所以这就是循环的目的。)

////// 这里是试验和错误代码,用于初始化和构建二维矩阵,以便从“CSV文件”中读取和存储矩阵 //////

///*
NSMutableArray *ppp = [NSMutableArray arrayWithCapacity:2];
NSMutableArray *kkk = [NSMutableArray arrayWithCapacity:20];

NSNull *myNull = [NSNull null];
for (int i=0; i<9; i++) {
    //[kkk addObject: [NSMutableString stringWithFormat: @"%d",i]];
    [kkk addObject: myNull];
}
//[kkk addObject: nil];

[ppp addObject:kkk];
[ppp addObject:kkk];
//*/


/*
// this is successful --> just uncomment this block and comment out the block above
[ppp addObject:[[NSMutableArray alloc] initWithObjects:
             @"z1",
             @"z2",
             @"z3",
             @"z4",
             @"z5",
             @"z6",
             @"z0gg",
             @"z0hh",
             @"z0ii",
             @"z0jj",
             nil
             ]];

[ppp addObject:[[NSMutableArray alloc] initWithObjects:
        @"a1",
        @"b2",
        @"c3",
        @"d4",
        @"e5",
        @"f6",
        nil
        ]];

*/

[[ppp objectAtIndex:0] replaceObjectAtIndex:1 withObject:@"HOTDOG"];
[[ppp objectAtIndex:1] replaceObjectAtIndex:1 withObject:@"HOHO"];
// HOHO will replace HOTDOG as well for the code not using "nil"

1
这可能是 如何向 NSMutableArray 添加 nil? 的重复问题。 - Chris Frederick
1
initWithObjects 中,nil 不会成为数组的一部分。请检查我的答案。 - sidyll
1
再次强调:在 initWithObjects: @"blank", @"blank", @"blank", ... nil 中,nil 不是 数组的一部分。 - sidyll
当然。如果你写了10个文本内容,你会有10个不同的对象。如果你在循环中添加它们,这10个对象将指向同一个文本内容。但我再次声明:在 initWithObjects: @"blank", @"blank", @"blank", ... nil 中,nil 不是 不是 不是 数组的一部分。 - sidyll
3
是的,你必须在最后一个参数中指定一个空值(nil),但这个nil只是一个标记值,用于表示列表的结尾,这个nil不会被存储在数组中。 - Rudy Velthuis
显示剩余9条评论
3个回答

13

当你尝试将nil添加到NSMutableArray中时会导致异常,详情请参考苹果官方文档

不过可以使用NSNull代替。

NSNull *myNull = [NSNull null];
[myMutableArray addObject:myNull];

你可能会问自己为什么要尝试做这件事,然而。


1
哈哈,你比我先回答了这个问题。 - Chris Frederick
我尝试了这个方法,和不加“nil”一样出现了问题。但是NSNull在其他方面会很有用。 - jdl
1
-addObject: 方法的命名有点不太清晰。你并没有向数组中添加对象的唯一副本,而是添加了一个指向该对象的引用(在 ObjC 中,你增加了它的保留计数器)。因此,当你更改引用中的内容时,它将影响到所有引用它的地方。换句话说,通过两次执行 [ppp addObject:kkk];,你向 ppp 添加了两个 kkk 的引用。当你使用 -replaceObjectAtIndex: 方法更改 ppp 的“第一个”对象中的 kkk 时,这种更改会影响到“第二个” kkk 所持有的内容(实际上只有一个 kkk)。 - Alex Reynolds
1
为了验证这一点,您可以添加一个可变数组称为kkk2,并在将其添加到ppp可变数组后进行类似的构造和修改。然后观察它的行为。它应该表现得像是唯一的,因为它是一个单独的对象(而不是对同一对象的第二个引用)。 - Alex Reynolds
刚在评论中说了同样的话。谢谢Alex澄清。这让我感觉更好 :-) - sidyll
显示剩余2条评论

9
您不需要在数组中将nil作为最后一个元素。
请勿将可变参数方法(如+arrayWithObjects:)与其混淆,该方法接收可变数量的参数,然后需要找到哪一个是最后一个。这是因为在这些方法实现(以及可变C函数)中,您无法检索传递的参数数量,因此nil标记了结尾。
通常情况下,您可以嵌套循环的次数与维度相同。在您的情况下,这将使用不同的对象填充“2D”数组:
NSMutableArray *array = [NSMutableArray array];
int i,j;

for (i = 0; i < 2; ++i) {
    NSMutableArray *s_array = [NSMutableArray array];
    [array addObject:s_array];
    for (j = 0; j < 8; ++j) {
        [s_array addObject:[NSString stringWithFormat:@"%d%d", i, j]];
    }
}

@jdl:为什么非空结尾的数组中不能替换对象?我确信是可以的! - sidyll
当我替换一个项目时,不知何故所有项目都受到了最后一个“替换”的影响。 - jdl
@jdl:你的代码清楚地表明,在第一种情况下,你创建了一个包含10个对象的数组,然后将这个数组两次添加到数组“ppp”中。因此,“ppp”包含2组10个对象。这10个对象在两个数组中都是相同的。这些对象并没有被“复制”,它们的引用被复制了。在第二种情况下,你创建了不同的对象。更具体地说,你创建了2组不同的对象。这与是否包括nil无关。同样,“initWithObjects”中的nil 不是数组的一部分 - sidyll
好的,底线是我正在尝试为矩阵创建空间。根据您所说,我需要为每一列创建一个循环来创建空间。??? 有更简单的方法吗?谢谢。 - jdl
1
对于 nil 与可变参数函数的关系,如果能给出一个好的解释,我会点赞。 - Alex Reynolds
@jdl:是的,但还有更简单的方法。谢谢 @Alex - sidyll

2
您不可以添加nil ..(也没必要这样做)。

1
以下是有关编程的内容,请将其翻译成中文。只返回翻译文本:+1 表示简洁和正确的答案,也可以帮助您获得 3k :-) - sidyll

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接