"-arrayWithArray"实际上是做什么的?

9

我想确切地了解它是如何创建一个数组的。我该如何查看展示其创建过程的 .m 文件?

4个回答

16

正如@Ken所提到的,您无法查看源代码(尽管您可以通过gdb反汇编该方法)。

该方法本身创建了一个给定数组的不可变(无法更改),自动释放副本。以下行为相同:

// Both resulting arrays are immutable and won't be retained
NSArray* immutableArray = [[[NSArray alloc] initWithArray:mutableArray] autorelease];
NSArray* immutableArray = [NSArray arrayWithArray:mutableArray];
NSArray* immutableArray = [[mutableArray copy] autorelease];

根据简洁程度选择您喜欢的任何一种,我想 :-).


嗯...它是不可变的?那么我需要给新数组中的每个对象发送额外的释放消息(使用alloc init),以便没有泄漏。如何释放不可变数组中的所有对象? - RexOnRoids
当对象被添加到数组中时,它们会被数组保留,因此当释放数组时,数组内的对象也应该被释放。 - slf
为什么需要创建一个新数组来向对象发送释放消息?不可变意味着数组本身不能被改变,但你可以随时改变(或向其中的对象发送消息)...或者更好的方法是,在将对象添加到数组之前自动释放它们,这样你就不用担心任何问题了。 - Kendall Helmstetter Gelner

2
不,Cocoa不是开源的。
如果你有问题,应该直接问。
以下是一个有效的实现方式:
+ (id)arrayWithArray:(NSArray *)array {
    return [[[self alloc] initWithArray:array] autorelease];
}

你可以阅读GNUStep源代码中NSArray的内容,但请注意这是Cocoa API的替代实现。


2
如果你问+arrayWithArray的作用(除了封装-initWithArray并使其自动释放),我会说它是这样的:当你想要创建一个自动释放的数组副本时,可以使用它。换句话说,你可以这样理解它:
NSArray * original = /* ... */;
NSArray * newArray = [NSArray arrayWithArray:original];

相当于:

NSArray * original = /* ... */;
NSArray * newArray = [[original copy] autorelease];

我认为它的存在是为了方便你在适合自己风格的情况下使用。


1
这并不完全正确。你的假设是original是一个NSArray。但它可以是从NSArray派生出来的任何东西。而且对象的类可以实现自己的copy。因此,[[original copy] autorelease];不能保证返回一个NSArray。 - Coyote

0

GNUstep是GNU实现的OPENSTEP规范,Cocoa和Cocoa Touch都是由此衍生而来。它将+arrayWithArray:实现如下:

/**
 * Returns a new autoreleased NSArray instance containing all the objects from
 * array, in the same order as the original.
 */
+ (id) arrayWithArray: (NSArray*)array
{
  id    o;

  o = [self allocWithZone: NSDefaultMallocZone()];
  o = [o initWithArray: array];
  return AUTORELEASE(o);
}

http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Source/NSArray.m?view=markup


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