在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,没有什么阻止你这样做。 在很多情况下,使用malloc
和free
可以避免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
,以便根据需要保留和释放它。 请注意,这不是绝对必要的 – 如果这种结构是您的程序的主要部分,它可能会很方便。