返回C阵列和内存管理

时间:2011-03-22 05:32:10

标签: objective-c c arrays mapkit return

我对MapKit中类points的以下属性MKMultiPoint感到有些困惑:

@property (nonatomic, readonly) MKMapPoint *points

它返回一个struct数组。可以使用pointCount属性知道数组中元素的数量。

由于我对C的了解有限,我一直以为C-arrays只能通过引用函数传递“返回”,因为调用者负责分配内存然后释放它。

如果我要写一个类似的属性,谁会为数组(可能是被调用者)分配内存,更重要的是谁会释放它(可能是调用者)?这对我来说听起来有点危险。此外,上述财产的文件没有说明必须释放记忆。

我错过了什么?

2 个答案:

答案 0 :(得分:3)

(示例代码在C中)。

好的做法是在同一级别分配和释放资源。有两种方法可以定义一个返回一系列事物的函数:

// `points` are allocated and freed by the caller.
void MakePoints (MKMapPoint *points, size_t number_of_points);

// usage:
size_t count = 10;
MKMapPoint *points = malloc (sizeof (MKMapPoint) * 10);
MakePoints (points, count);

// Use points

free (points);

// or simply
MKMapPoint points[10];
MakePoints (points, 10);

// Use points

第二种方法是让库函数管理内存:

MKMapPoint *MakePoints (size_t number_of_points);
void FreePoints (MKMapPoint *points);

// Usage:
MKMapPoint *points = MakePoints (10);

// Use points

// The library need not necessarily call free() on points,
// it might reuse it in further calls to MakePoints().
FreePoints (points);

答案 1 :(得分:0)

在大多数情况下,接收器将处理分配内存。谁释放它取决于你如何确定所有权。一旦返回,接收器分配的内存是否不再需要?如果是这样,您应该在文档中注意调用者需要释放返回的数组。如果接收方可以重用返回的内存,请将其重新分配给它。

如果你想把它留给被调用者处理内存分配,你可能不会使用属性而是选择一个消息和属性,如下所示:

- (NSUInteger) mapPointCount;
- (void) getMapPoints:(MKMapPoint *)pointsOut;

发件人应该提供一个现有缓冲区来存储obj.mapPointCount个MKMapPoints。然后,你已经在调用者身上放置了分配/解除分配的责任。

如果你不想走那条路,并且由于接收器无法保留/释放/自动释放有问题的内存,我会将其留给呼叫者释放它。如果您想要明确表示不要释放内存,请使用类型const MKMapPoint *以某种形式的文档注明它(这应该很清楚访问数据的人不拥有内存。)

或者,将其存储在NSData或其他内容中并清楚地表明,一旦下一个自动释放池耗尽,指针就无效了。然而,这有点不太友好,垃圾收集可能不安全。最后一点可能是错的,但我不知道该怎么说,所以我现在更加谨慎。