objective-c - 从在 ARC 下包装第 3 方 C++ 对象的类返回 C 样式数组是否安全?

标签 objective-c arrays static-libraries wrapper

我正在使用用 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;
}

我的问题:

  1. 对于返回 double * 的函数,我没有收到错误/崩溃,这是否是侥幸?或者出于某种原因这可以吗?

  2. 更大的问题:为什么转换为 NSArray 仍然有效? ?为什么 ARC 不释放 wrappedObj->getCoefficients() 中创建的内存这样CarraymyGetCoefficients 中变得不可用?

最佳答案

如果这是最后一次使用,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/

相关文章:

ios - NSString 不会添加到 NSMutableArray

javascript - 返回行号匹配错误

c++ - 您如何在数组的特定位置插入数字?

javascript - 迭代数组中未定义的方法

c++ - 从 Visual Studio 2017 引用静态库有多简单?

c++ - 库内外特化的模板类

ios - AFNewtorking 从 Amazon S3 加载图像

iphone - 最大 CAShapeLayer 大小?

ios - 如何删除 GPPSignInButton 的默认样式(文本、G+ 图像)以在 iOS 中添加您自己的样式

c++ - 如何部署C静态库: header + c file or object file?