Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 返回C阵列和内存管理_Objective C_C_Arrays_Mapkit_Return - Fatal编程技术网

Objective c 返回C阵列和内存管理

Objective c 返回C阵列和内存管理,objective-c,c,arrays,mapkit,return,Objective C,C,Arrays,Mapkit,Return,我对MapKit中类MKMultiPoint的以下属性points有点困惑: @property (nonatomic, readonly) MKMapPoint *points 它返回一个struct数组。使用pointCount属性可以知道数组中的元素数 由于我对C的了解有限,我一直认为C数组只能通过引用传递给函数才能“某种程度上返回”,因为调用方负责分配内存,然后释放内存 如果我要编写一个类似的属性,谁会为数组(可能是被调用方)分配内存,更重要的是谁会释放它(可能是调用方)?这听起来有点

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

@property (nonatomic, readonly) MKMapPoint *points
它返回一个struct数组。使用
pointCount
属性可以知道数组中的元素数

由于我对C的了解有限,我一直认为C数组只能通过引用传递给函数才能“某种程度上返回”,因为调用方负责分配内存,然后释放内存

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


我遗漏了什么?

在大多数情况下,接收器将负责分配内存。谁来释放它取决于你如何决定所有权。接收器分配的内存在返回后是否不再需要?如果是这样,您可能应该在文档中注意调用方需要释放返回的数组。如果接收器可以重用返回的内存,则将释放留给它

如果您想让被调用方处理内存分配,您可能不会使用属性,而是选择消息和属性,如下所示:

- (NSUInteger) mapPointCount;
- (void) getMapPoints:(MKMapPoint *)pointsOut;
其中,发送方应提供一个现有缓冲区,以存储中的MKMapPoints的数量
obj.mapPointCount
。然后,您将分配/解除分配的责任交给了调用者

如果你不想走这条路,而且由于接收者不能保留/释放/自动释放内存,我会让调用者来释放它。如果您想清楚地表明内存不会被释放,请使用类型
const MKMapPoint*
返回它,并在某种形式的文档中记录它(希望能够清楚地表明,内存不是由访问数据的人拥有的)

或者,将其存储在NSData或其他文件中,并明确指出,一旦下一个自动释放池耗尽,指针无效。然而,这有点不友好,垃圾收集可能不安全。最后一点可能是错误的,但我不知道该怎么说,所以我现在更希望谨慎。

(示例代码是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);

嗨@Vijay Mathew,谢谢你的回答。我理解你的两个例子,但它们似乎与我给出的不匹配。在MKMultiPoint属性中,返回数组,而不是传入参数。这将强制接收方分配内存,而不是像points属性那样分配调用者。至于第二个例子,文档中没有提到返回数组的“空闲内存”函数。这是否意味着调用方应该使用free()C函数释放内存?您好@nil,感谢您的回答,强调了文档在这种特定情况下的重要性。我假设苹果文档中关于
MKMultiPoint
points
属性缺少一些内容。给定该方法的签名,我看不到调用方可以释放内存的任何其他选项。否则,它们将是一个漏洞,对吗?我不知道,但我的假设是,如果没有关于它的注释,对象拥有指针并将处理释放。如果它被证明是一个漏洞,你可以试着稍后释放它,看看它是否会停止——最好假设它不是一个漏洞(因为你可能可以通过一些简单的测试检测到这个漏洞(如果它是一个),而不是写一些看起来运行良好的东西,然后一个月后,由于
免费(…)
你不会怀疑的。我现在意识到,我完全写了这个问题的答案,但总体上误解了这个问题。这可能没有任何帮助。