Objective c 返回C阵列和内存管理
我对MapKit中类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数组只能通过引用传递给函数才能“某种程度上返回”,因为调用方负责分配内存,然后释放内存 如果我要编写一个类似的属性,谁会为数组(可能是被调用方)分配内存,更重要的是谁会释放它(可能是调用方)?这听起来有点
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
属性缺少一些内容。给定该方法的签名,我看不到调用方可以释放内存的任何其他选项。否则,它们将是一个漏洞,对吗?我不知道,但我的假设是,如果没有关于它的注释,对象拥有指针并将处理释放。如果它被证明是一个漏洞,你可以试着稍后释放它,看看它是否会停止——最好假设它不是一个漏洞(因为你可能可以通过一些简单的测试检测到这个漏洞(如果它是一个),而不是写一些看起来运行良好的东西,然后一个月后,由于免费(…)
你不会怀疑的。我现在意识到,我完全写了这个问题的答案,但总体上误解了这个问题。这可能没有任何帮助。