将NSArray转换为CFStringRef *

埃里克·伯格伦德(Erik Berglund)

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

文档将参数选项指定为类型的“空终止列表” CFStringRef arguments[]

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

我已经尝试过了,但是我总是遇到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));

给出以下错误信息:

ARC不允许将非目标C指针类型'void *'隐式转换为'__strong id *'

指向没有显式所有权的非常量类型“ id”的指针。

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

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

然后这行:

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

给出以下错误:

[错误] ARC不建议将Objective-C指针隐式转换为'__unsafe_unretained id *'

[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的调用中,出现以下错误:

ARC不允许将Objective-C指针强制转换为'CFStringRef *'(aka'const struct __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 *

肯·托马斯(Ken Thomases)

尝试这个:

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()它不为您提供返回值的所有权。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章