在Objective-C / iPhone应用程序中使用“classic”malloc()/ free()可以吗?

我一直在玩iPhone开发一段时间,虽然当你是一个“硬核”的.NET开发人员时,感觉有些尴尬,但是一旦你习惯了它,并不是那么糟糕。

在我读到的关于Objective-C的每本书中,都只提到了内存pipe理的保留/释放(引用计数)。 作为一个老式的C / C ++开发者,使用malloc()和free()分配“正常”的方式似乎很奇怪,只是在脚注中提到。

我知道malloc()和free()在Objective-C中的工作,但我很好奇,如果这是普遍的做法或不。 毕竟,如果我想分配一个100个整数的数组,似乎这是最有效的方法:

int *array = malloc(sizeof(int) * 100); memset(array,0,sizeof(int) * 100); // use the array free(array); 

这确实是最好的方法,还是应该避免纯C内存pipe理?

这非常好 – Objective-C是C的一个严格的超集,所以如果你想写简单的C,没有什么阻止你这样做。 在很多情况下,使用mallocfree可以避免Objective-C运行时的开销。

例如,如果您需要dynamic分配一个未知数量的数组,它通常更简单和更容易:

 int *array = malloc(N * sizeof(int)); // check for NULL return value! // use array[0]..array[N-1] ... free(array); 

与:

 NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:N]; // use NSMutableArray methods to do stuff with array; must use NSNumbers instead // of plain ints, which adds more overhead ... [array release]; 

我正在为iPhonedevise一个文字游戏,我们不得不加载一个有效字的多字节字典。 单词列表被加载到malloc()分配的一个巨型char数组中,并进行了一些巧妙的优化,以减less内存大小。 显然对于这样的事情,使用NSArray的开销在有限的iPhone上是完全不切实际的。 我不知道开销是多less,但是每个字符肯定不止一个字节。

有一个围绕原始内存的Objective-C包装,我喜欢用它来做类似的任务: NSMutableData 。 它具有让您保留/释放所有权的好处,并且可以轻松地增加数组(无需您自己执行重新分配)。

你的代码如下所示:

 NSMutableData* data = [NSMutableData dataWithLength:sizeof(int) * 100]; int* array = [data mutableBytes]; // memory is already zeroed // use the array // decide later that we need more space: [data setLength:sizeof(int) * 200]; array = [data mutableBytes]; // re-fetch pointer in case memory needed to be copied // no need to free // (it's done when the autoreleased object is deallocated) 

当然,你可以使用这些函数,因为Objective-C只是C的一个超集。然而,做这种事情是相当罕见的,因为Objective-C包含了对象和方法来简化它。

毕竟,你可以写上面的代码为:

 NSMutableArray *array = [[NSMutableArray alloc] init]; //Use the array, adding objects when need be [array release]; 

虽然你将不得不创buildNSNumber对象来存储int (因为NSArray不允许添加非对象types),所以使用对象通常更为常见,因为移动数据比较容易,数组类与其他Cocoa类更为常见,内存pipe理通常比标准C内存pipe理更直接。

另外,如果你开始向数组中添加或删除对象,那么Cocoa数组对象使得这更容易做到。

使用malloc和free来做自己的内存pipe理是非常好的。 实际上NSObject的allocWithZone:使用malloc来获取内存。

如果你正在处理标准的Ctypes,那么它就不会像C中那么常见或者说“OK”。这就是Objective-C中C语言的一部分。

在这些东西上写一些对象包装来使其与其他cocoa(KVO,内存pipe理等)协调一致也是很平常的。 因此,您可以创build一个IntArray类,在后台执行malloc ,以便根据需要保留和释放它。 请注意,这不是绝对必要的 – 如果这种结构是您的程序的主要部分,它可能会很方便。