当我将C数组传递给Objective-C方法时,让方法将数组复制到堆内存是否足够?

时间:2013-08-07 14:44:52

标签: objective-c c

示例:

unsigned char colorComps[] = {2, 3, 22,   55, 9, 1};

将此传递给Objective-C方法,该方法使用属性引用它。需要先将其复制到堆内存中。但是为了安全起见,让方法执行此步骤还是将其复制到堆中然后将其传递给方法是否可以?

3 个答案:

答案 0 :(得分:3)

在我使用的几乎所有C API中,惯例是被调用的函数负责在需要时复制数据。

这是有道理的,因为被调用函数知道需要多长时间,而调用者则不知道。由于性能原因我们通常使用C,这也避免了不必要的内存分配和复制。

在这方面,除非你有使用C数组的性能原因,否则只需使用NSNumber的NSNrray。更简单。

答案 1 :(得分:2)

与将数组传递给C函数的规则完全相同。 Objective-C中没有关于C数组的特殊处理。除非您不能声明具有C数组类型的属性。有关变通方法,请参阅this questionthis question。在这种情况下,您的对象(希望公开数组)应该分配内存,复制数组并在适当时释放它。将它“分配”在“外部”然后将其“释放”在内部是一个坏主意。

除非你真的需要一个C数组(例如,因为你有一个第三方库需要它作为参数而你需要一直构建它)你应该坚持使用Objective-C对象(NSArrays中的NSNumbers)。特别是因为语法现在非常简单:

NSArray *myArray = @[ @(1), @(42), @(543) ];

使用C数组只是“因为它们更快”将是预先成熟的优化,除非您实际测量过NSArray / NSNumber解决方案是您的瓶颈。我正在iOS上进行多媒体处理,出于性能原因,我从未必须从NSArray切换到C阵列。

答案 2 :(得分:2)

我相信你在前一个问题上询问my comment,所以让我解释一下。

如果你只是接受你收到的任何数组并保持原样,你就无法控制它;你将代码的完整性完全留给了调用函数。您可能会意外忘记传入副本,或者传入字符串文字*,然后您有一个可能很难找到的错误。通过使用属性并将ivar设置为您创建的数组,您可以控制它。您确切地知道它的预期寿命,并且您知道在dealloc中释放它是安全的(实际上是必需的)。

请注意,这就是为什么应始终声明块属性copy的原因。如果您只是在收到它时保持块,它将无效并导致以后出现问题,除非它已经在某个时候被复制到堆中。但是当你将它传递给一个函数时,你通常不会copy一个块,你调用的函数负责确保它可以安全地存在。

*:是的,你使用它的方式不太可能,但在不同情况下可能会引起关注。