我正在使用用 C++ 实现的第 3 方静态库。我将该对象包装在 h
中的自定义 ObjC 对象中和mm
文件,基本上遵循here描述的方法。库中的许多函数返回 int
的 C 风格数组。或double
s。例如,在 thirdParty.h/.cpp 中:
const double * getCoefficients()
myThirdPartyWrapper.mm 中的包装器代码如下所示:
@interface myThirdPartyWrapper ()
{
thirdPartyObject *wrappedObj;
}
@end
@implementation myThirdPartyWrapper
- (id)init
{
self = [super init];
if (self)
{
// Create third-party object
wrappedObj = new thirdPartyObject;
if (!wrappedObj) self = nil;
}
return self;
}
- (void)dealloc
{
delete wrappedObj;
// Don't need [super dealloc] since we are using ARC
}
- (const double *)myGetCoefficients
{
return wrappedObj->getCoefficients();
}
然后,回到我的 .m 文件:
myThirdPartyWrapper *wrapper = [[myThirdPartyWrapper alloc] init];
const double *coeff = [wrapper myGetCoefficients];
// etc...
对于返回 double *
的函数来说,这似乎对我来说没问题。但返回 double **
时崩溃。然后我读到在 Objective-C 中返回 C 风格的数组是不安全的,因为函数中局部变量指向的内存被 ARC 释放,所以(在我的例子中)coeff
不会指出任何内容。所以我应该这样做:
- (NSArray *)myGetCoefficients
{
double *Carray = wrappedObj->getCoefficients();
NSArray *array = [[NSArray alloc] init];
for (int i = 0; i < numItems; i++)
[array addObject:[NSNumber numberWithDouble:Carray[i]]];
return array;
}
我的问题:
对于返回
double *
的函数,我没有收到错误/崩溃,这是否是侥幸?或者出于某种原因这可以吗?更大的问题:为什么转换为
NSArray
仍然有效? ?为什么 ARC 不释放wrappedObj->getCoefficients()
中创建的内存这样Carray
在myGetCoefficients
中变得不可用?
最佳答案
如果这是最后一次使用,ARC 可以在调用 -myGetCoefficients
后立即释放 wrapper
。当它释放它时,可能会导致其释放,这将释放 C++ 对象及其系数数组。
使用 NS_RETURNS_INNER_POINTER
注释您的 -myGetCoefficients
方法:
- (const double *)myGetCoefficients NS_RETURNS_INNER_POINTER
{
// ...
}
这告诉 ARC 保留接收器,以尝试使返回的指针保持更长时间的有效状态。根据the docs ,它的生命周期至少会延长到:
- 最后一次使用返回的指针或从它派生的任何指针, 在调用函数中或
- 自动释放池恢复到之前的状态。
关于objective-c - 从在 ARC 下包装第 3 方 C++ 对象的类返回 C 样式数组是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25477286/