9

我想创建一个具有相同值对象的 NSArray(比如 NSNumber 全部初始化为 1),但计数基于另一个变量。除了处理 C 样式数组的初始化程序之外,似乎没有办法使用 NSArray 的任何初始化程序来做到这一点。

知道是否有一种简短的方法可以做到这一点吗?

这就是我要找的:

NSArray *array = [[NSArray alloc] initWithObject:[NSNumber numberWithInt:0]
                                           count:anIntVariable];

NSNumber 只是这里的一个例子,它本质上可以是任何 NSObject。

4

4 回答 4

15

我为此编写的最严格的代码是:

id numbers[n];
for (int x = 0; x < n; ++x)
    numbers[x] = [NSNumber numberWithInt:0];
id array = [NSArray arrayWithObjects:numbers count:n];

这是因为您可以使用 Xcode 默认使用的 C99 创建运行时长度确定的 C 数组。

如果它们都是相同的值,您也可以使用 memset (尽管转换为 int 很顽皮):

id numbers[n];
memset(numbers, (int)[NSNumber numberWithInt:0], n);
id array = [NSArray arrayWithObjects:numbers count:n];

如果你知道你需要多少个对象,那么这段代码应该可以工作,虽然我还没有测试过:

id array = [NSArray arrayWithObjects:(id[5]){[NSNumber numberWithInt:0]} count:5];
于 2011-11-02T10:58:04.630 回答
3

我看不出为什么这种非可变格式的结构会有用,但我确信你有你的理由。

我认为您别无选择,只能使用 NSMutableArray,使用 for 循环构建它,如果结果不可变真的很重要,请构造一个 NSArray 并使用 arrayWithArray:

于 2009-07-01T22:38:51.697 回答
2

我同意@mmc,请确保您有正当理由拥有这样的结构(而不​​是仅使用同一个对象 N 次),但我假设您这样做。

还有另一种构造不可变数组的方法,它会稍微快一些,但它需要创建一个 C 对象数组并将其传递给 NSArray 的+arrayWithObject:count:方法(请注意,它返回一个自动释放的数组),如下所示:

id anObject = [NSNumber numberWithInt:0];
id* buffer = (id*) malloc(sizeof(id) * anIntVariable);
for (int i = 0; i < anIntVariable; i++)
  buffer[i] = anObject;
NSArray* array = [NSArray arrayWithObjects:buffer count:anIntVariable];
free(buffer);

你可以用更复杂的指针数学来完成同样的事情,但收益相当微不足道。无论如何,如果您有兴趣,请发表评论。

于 2009-07-01T23:09:28.500 回答
2

NSArray 上没有这种方法的原因可能是语义没有很好地定义。对于您的情况,使用不可变的 NSNumber,那么所有不同的语义都是等价的,但想象一下,如果您添加的对象是可变对象,例如 NSMutableString。

存在三种不同的语义:

  • 保留——你最终会得到十个指向同一个可变字符串的指针,改变任何一个都会改变所有十个。

  • 复制——你最终会得到十个指向同一个不可变字符串的指针,或者可能有十个不同的指向具有相同值的不可变字符串的指针,但无论哪种方式,你都无法更改它们中的任何一个。

  • mutableCopy — 你最终会得到十个不同的可变字符串对象,其中任何一个都可以独立更改。

因此,Apple 可以编写该方法的三个变体,或者具有某种参数来控制语义,这两者都很丑陋,因此他们将其留给您编写代码。如果需要,可以将其添加为 NSArray 类别方法,只需确保您了解语义选项并说明清楚即可。

方法:

-(id)initWithArray:(NSArray *)array copyItems:(BOOL)flag

有同样的问题。

Quinn 使用 arrayWithObjects:count: 的解决方案是一个相当不错的解决方案,可能是您在一般情况下可以获得的最佳解决方案。把它放在一个 NSArray 类别中,就可以达到它的效果。

于 2009-07-02T03:11:00.667 回答