将NSArray转换为CFStringRef *

时间:2015-03-27 21:23:34

标签: objective-c nsarray cfstring diskarbitration

我需要一种方法将 NSArray 转换为与 DADiskMountWithArguments 的arguments选项兼容的空终止列表。

文档将参数选项指定为" Null终止列表"类型为CFStringRef arguments[]

我创建了一个Mount方法,我想用参数传递 NSArray ,在我的方法中我需要将 NSArray 转换为CFStringRef *。 / p>

我已经尝试过了,但我总是遇到ARC问题,而且我还没有找到任何好办法。

我已经在GitHub https://github.com/aburgh/Disk-Arbitrator/blob/master/Source/Disk.m中查看了Disk-Arbitrator项目的灵感,该应用程序的创建者使用了这种方法:

- (void)mountAtPath:(NSString *)path withArguments:(NSArray *)args
{
    NSAssert(self.isMountable, @"Disk isn't mountable.");
    NSAssert(self.isMounted == NO, @"Disk is already mounted.");

    self.isMounting = YES;

    Log(LOG_DEBUG, @"%s mount %@ at mountpoint: %@ arguments: %@", __func__, BSDName, path, args.description);

    // ensure arg list is NULL terminated
    id *argv = calloc(args.count + 1, sizeof(id));

    [args getObjects:argv range:NSMakeRange(0, args.count)];

    NSURL *url = path ? [NSURL fileURLWithPath:path.stringByExpandingTildeInPath] : NULL;

    DADiskMountWithArguments((DADiskRef) disk, (CFURLRef) url, kDADiskMountOptionDefault,
                         DiskMountCallback, self, (CFStringRef *)argv);

    free(argv);
}

但ARC不允许这样做,我无法找到办法。

更新以获得更清晰:

这一行:

id *argv = calloc(args.count + 1, sizeof(id));

给出以下错误消息:

  

非Objective-C指针类型的隐式转换' void *'至   ' __强身份证*'不允许使用ARC

     

指向非const类型' id'没有明确的所有权。

要解决这个问题,我尝试这样做:

id argv = (__bridge id)(calloc(args.count + 1, sizeof(id)));

然后这一行:

[args getObjects:argv range:NSMakeRange(0, args.count)];

给出以下错误:

  

[ERROR]将Objective-C指针隐式转换为   ' __ unsafe_unretained id *'不允许使用ARC

     

[WARN]不兼容的指针类型发送' __ string id'参数   类型' __ unsafe_unretained id *'

-getObjects:range:的声明如下所示:

- (void)getObjects:(id [])aBuffer range:(NSRange)aRange

所以从我得到的错误消息中我假设我必须传递一个' __ unsafe_unretained id *'到' getObjects:(id [])aBuffer'。所以要解决这个问题,我将我的id声明为__unsafe_unretained,如下所示:

__unsafe_unretained id argv = (__bridge __unsafe_unretained id)(calloc(args.count + 1, sizeof(id)));

并像这样更新这一行:

[args getObjects:&argv range:NSMakeRange(0, args.count)];

现在我没有任何错误,但在调用 DADiskMountWithArguments 时出现以下错误:

  

将Objective-C指针转换为' CFStringRef *' (又名' const struct   ARC不允许__CFString **)

所以我在这里陷入困境,因为我无法解决这个错误,而且我不知道我之前是否犯过错误,或者我是否找不到正确的方式发送CFStringRef,因此我决定在这里寻求指导。

这是它在上下文中的样子,其中args是先前声明的 NSArray

__unsafe_unretained id argv = (__bridge __unsafe_unretained id)(calloc(args.count + 1, sizeof(id)));

[args getObjects:&argv range:NSMakeRange(0, args.count)];

DADiskMountWithArguments((DADiskRef) disk, (__bridge CFURLRef) url, kDADiskMountOptionDefault, NULL, (__bridge void *)self, (CFStringRef *)argv );

所以我的问题是,这个方法怎么能成为ARC友好的,或者是否有另一种/更好的方法从 NSArray 到一个以NULL结尾的CFStringRef *

1 个答案:

答案 0 :(得分:1)

试试这个:

CFStringRef *argv = calloc(args.count + 1, sizeof(CFStringRef));
CFArrayGetValues((__bridge CFArrayRef)args, CFRangeMake(0, args.count), (const void **)argv );
DADiskMountWithArguments((DADiskRef) disk, (CFURLRef) url, kDADiskMountOptionDefault,
                     DiskMountCallback, self, argv);
free(argv);

没有Core Foundation / Cocoa内存管理问题,因为CFArrayGetValues()并未授予您返回值的所有权。

相关问题