objective-c 创建一个用计数 N 初始化的 NSArray,所有的对象都是相同的

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1071648/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 21:50:31  来源:igfitidea点击:

Creating an NSArray initialized with count N, all of the same object

objective-ccocoainitializationnsarray

提问by Boon

I want to create an NSArray with objects of the same value (say NSNumber all initialized to 1) but the count is based on another variable. There doesn't seem to be a way to do this with any of the intializers for NSArray except for one that deals with C-style array.

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

Any idea if there is a short way to do this?

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

This is what I am looking for:

这就是我要找的:

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

NSNumber is just one example here, it could essentially be any NSObject.

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

回答by mxcl

The tightest code I've been able to write for this is:

我能够为此编写的最紧凑的代码是:

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

This works because you can create runtime length determined C-arrays with C99 which Xcode uses by default.

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

If they are all the same value, you could also use memset (though the cast to int is naughty):

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

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

If you know how many objects you need, then this code shouldwork, though I haven't tested it:

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

id array = [NSArray arrayWithObjects:(id[5]){[NSNumber numberWithInt:0]} count:5];

回答by mmc

I can't see any reason why this structure in a non-mutable format would be useful, but I am certain that you have your reasons.

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

I don't think that you have any choice but to use a NSMutableArray, build it with a for loop, and if it's really important that the result not be mutable, construct a NSArray and use arrayWithArray:

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

回答by Quinn Taylor

I agree with @mmc, make sure you have a valid reason to have such a structure (instead of just using the same object N times), but I'll assume you do.

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

There is another way to construct an immutable array which would be slightly faster, but it requires creating a C array of objects and passing it to NSArray's +arrayWithObject:count:method (which returns an autoreleased array, mind you) as follows:

还有另一种构造不可变数组的方法会稍微快一点,但它需要创建一个 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);

You could accomplish the same thing with even trickier pointer math, but the gains are fairly trivial. Comment if you're interested anyway.

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

回答by Peter N Lewis

Probably the reason there is no such method on NSArray is that the semantics are not well defined. For your case, with an immutable NSNumber, then all the different semantics are equivalent, but imagine if the object you were adding was a mutable object, like NSMutableString for example.

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

There are three different semantics:

存在三种不同的语义:

  • retain— You'd end up with ten pointers to the same mutable string, and changing any one would change all ten.

  • copy— You'd end up with ten pointers to the same immutable string, or possibly ten different pointers to immeduable strings with the same value, but either way you'd not be able to change any of them.

  • mutableCopy— You'd end up with ten different mutable string objects, any of which you could change independently.

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

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

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

So Apple could write three variants of the method, or have some sort of parameter to control the semantics, both of which are ugly, so instead they left it to you to write the code. If you want, you can add it as an NSArray category method, just be sure you understand the semantic options and make it clear.

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

The method:

方法:

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

has this same issue.

有同样的问题。

Quinn's solution using arrayWithObjects:count: is a reasonably good one, probably about the best you can get for the general case. Put it in an NSArray category and that's about as good as it is going to get.

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