3

例子:

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

将此传递给使用属性引用它的 Objective-C 方法。需要先复制到堆内存。但是让方法执行此步骤是否可以,或者为了安全起见,我必须在将其传递给方法之前将其复制到堆中吗?

4

3 回答 3

3

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

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

关于这一点,除非你有使用 C 数组的性能原因,否则只需使用 NSNumber 的 NSArray。简单得多。

于 2013-08-07T14:52:58.683 回答
2

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

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

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

使用 C 数组只是“因为它们更快”将是过早的优化,除非您实际测量到 NSArray/NSNumber 解决方案对您来说是一个瓶颈。我在 iOS 上进行多媒体处理,出于性能原因,我从来不需要从 NSArray 切换到 C 数组。

于 2013-08-07T14:48:05.803 回答
2

我相信您是在询问对您之前问题的评论,所以让我解释一下。

如果您只是简单地获取收到的任何数组并保持原样,那么您将无法控制它;您将代码的完整性完全留给调用函数。你可能会不小心忘记传递一个副本,或者传递一个字符串文字*,然后你就有一个潜在的难以发现的错误。通过使用属性并将 ivar 设置为您创建的数组,您可以控制它。您准确地知道它所需的生命周期,并且您知道在dealloc.

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

*:是的,您使用它的方式不太可能,但在不同的情况下,这可能是一个问题。

于 2013-08-07T15:47:36.900 回答