NSArray 分配和初始化

NSArray alloc and init

我对 NSArray 初始化有点困惑。令人困惑的是我们有不同的 init 方法来初始化它,如果我只是初始化它而不给出任何大小和任何对象,编译器如何知道它在 RAM 中的对象计数或大小。 init 方法后面的 logic/difference 是什么?任何人都可以简要解释一下吗?

编辑:

NSArray *sortedArray = [[NSArray alloc] init];
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc]   initWithKey:@"quota" ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObject:descriptor];
//How is that possible to modifying to immutable object
sortedArray = [sortedContainers sortedArrayUsingDescriptors:sortDescriptors];

我知道 NSArrayNSMutableArray 之间的差异,但我并没有寻找差异。我只是想知道该代码如何 compile/execute 没有错误。

如果您只是初始化 NSArray 而没有给出任何大小和任何对象,它将在整个生命周期内保持为空。 NSArray 是不可变的

如果您的问题是关于 NSMutableArray,请阅读 here at the SO

[[NSArray alloc] init] returns 一个空的不可变数组。这并不奇怪。您 return 从方法中还有什么意思 "no items?"

how compiler knows it object count or size in RAM

对象计数为 0。它是空的。它在 RAM 中的大小是空 NSArray 的大小。 NSArray 是一个对象,所以它有一些标准的 objc_object 开销,加上 NSArray.

的一些实例变量

也就是说,作为一个实现细节,Cocoa 对此进行了优化,并且始终 return 对所有空 NSArray 对象使用相同的单例。您可以通过以下方式证明这一点:

NSArray *a = [[NSArray alloc] init];
NSArray *b = [[NSArray alloc] init];
NSLog(@"%p", a);
NSLog(@"%p", b);
if (a == b) { // Pointer equality, not isEqual:
    NSLog(@"Same object");
}

那么,这是在做什么?

NSArray *sortedArray = [[NSArray alloc] init]; // (1)
// ... code that doesn't matter ...
sortedArray = [sortedContainers sortedArrayUsingDescriptors:sortDescriptors]; // (2)

在第 1 行,您正在创建一个局部指针变量,sortedArray 并将其指向一个空数组(它恰好是一个单例,但这是一个优化细节)。

在第 2 行,您通过调用 sortedArrayUsingDescriptors: 创建了一个完全不同的 NSArray。然后,您将 sortedArray 指向该对象。 ARC 发现您不再指向空数组,并释放它。 (再次强调,优化细节跳到这里,实际步骤可能不同,但效果是一样的。)

这里的正确代码是:

// ... Code that sets up sortDescriptors ...
NSArray *sortedArray = [sortedContainers sortedArrayUsingDescriptors:sortDescriptors]; 

现在,在非常现代的 ObjC 中,您不会经常看到 [[NSArray alloc] init] 写出来。编写 @[] 更容易(这实际上只是方法调用的语法糖)。但是在数组文字被添加到语言之前,[[NSArray alloc] init][NSArray array] 相当普遍。