我一直在玩iPhone开发已经有一段时间了,虽然当你是一个“硬核”.NET开发人员时感觉有点尴尬,但是一旦你习惯它就不会那么糟糕。
在我读到的关于Objective-C的每本书中,只讨论了内存管理的保留/释放(引用计数)。作为一个老式的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内存管理?
答案 0 :(得分:79)
有一个关于原始内存的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)
答案 1 :(得分:48)
完全没问题 - Objective-C是C的严格超集,所以如果你想写简单的C,那么就没有什么能阻止你这么做了。在许多情况下,使用malloc
和free
来避免Objective-C运行时的开销是有利的。
例如,如果您需要动态分配一个未知数量的整数数组,那么它通常更简单,更容易:
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];
我正在为iPhone制作文字游戏,我们不得不加载一张有效字的数兆字典。单词列表被加载到一个分配有char
的巨型malloc()
数组中,并进行了一些巧妙的优化以进一步减少内存大小。显然,对于这样的事情,使用NSArray
的开销在有限的iPhone上是完全不切实际的。我不确切知道开销是多少,但每个字符肯定不止一个字节。
答案 2 :(得分:5)
当然,可以使用这些函数,因为Objective-C只是C的超集。但是,由于Objective-C包含了对象,所以这种情况很少见。如何使这更容易。
毕竟,你可以将上面的代码写成:
NSMutableArray *array = [[NSMutableArray alloc] init];
//Use the array, adding objects when need be
[array release];
虽然您必须创建NSNumber
个对象来存储int
s(因为NSArray
不允许添加非对象类型),所以通常更常见使用对象,因为它更容易移动数据,并且数组类更常与其他Cocoa类集成,并且内存管理通常比标准C内存管理更直接。
此外,如果您开始在数组中添加或删除对象,那么Cocoa数组对象使这更容易。
答案 3 :(得分:3)
如果您正在处理标准C类型,那么它与C语言相比并不常见或“OK”。这就是它在C语言中的表现,它是Objective-C的一部分。
在这些东西周围编写某种对象包装器以使其与Cocoa的其余部分(KVO,内存管理等)协调一致也并不罕见。因此,您可以创建一个IntArray类,在幕后执行malloc
,以便您可以根据需要保留和释放它。请注意,这不是绝对必要的 - 如果这种结构是您程序的主要部分,它可以很方便。
答案 4 :(得分:2)
使用malloc并自由地进行自己的内存管理是完全没问题的。实际上NSObject的allocWithZone:
使用malloc来获取内存。