将 NSArray 转换为 CFStringRef *
Convert NSArray to CFStringRef *
我需要一种方法将 NSArray 转换为与 DADiskMountWithArguments.[=23= 的参数选项兼容的空终止列表]
文档将参数选项指定为 CFStringRef arguments[]
类型的 "Null terminated list"。
我创建了一个 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));
给出以下错误信息:
Implicit conversion of a non-Objective-C pointer type 'void *' to
'__strong id *' is disallowed with ARC
Pointer to non-const type 'id' with no explicit ownership.
为了解决这个问题,我尝试这样做:
id argv = (__bridge id)(calloc(args.count + 1, sizeof(id)));
然后这一行:
[args getObjects:argv range:NSMakeRange(0, args.count)];
给出以下错误:
[ERROR] Implicit conversion of an Objective-C pointer to
'__unsafe_unretained id *' is disallowed with ARC
[WARN] Incompatible pointer types sending '__string id' to parameter
of type '__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 时我收到以下错误:
Cast of an Objective-C pointer to 'CFStringRef *' (aka 'const struct
__CFString **) is disallowed with ARC
所以我被卡住了,因为我无法修复这个错误,我不知道我是否之前犯了错误或者我没有找到发送 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 友好,或者是否有 another/better 方法从 NSArray 到 NULL 终止CFStringRef *
试试这个:
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);
没有核心 Foundation/Cocoa 内存管理问题,因为 CFArrayGetValues()
不给您返回值的所有权。
我需要一种方法将 NSArray 转换为与 DADiskMountWithArguments.[=23= 的参数选项兼容的空终止列表]
文档将参数选项指定为 CFStringRef arguments[]
类型的 "Null terminated list"。
我创建了一个 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));
给出以下错误信息:
Implicit conversion of a non-Objective-C pointer type 'void *' to '__strong id *' is disallowed with ARC
Pointer to non-const type 'id' with no explicit ownership.
为了解决这个问题,我尝试这样做:
id argv = (__bridge id)(calloc(args.count + 1, sizeof(id)));
然后这一行:
[args getObjects:argv range:NSMakeRange(0, args.count)];
给出以下错误:
[ERROR] Implicit conversion of an Objective-C pointer to '__unsafe_unretained id *' is disallowed with ARC
[WARN] Incompatible pointer types sending '__string id' to parameter of type '__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 时我收到以下错误:
Cast of an Objective-C pointer to 'CFStringRef *' (aka 'const struct __CFString **) is disallowed with ARC
所以我被卡住了,因为我无法修复这个错误,我不知道我是否之前犯了错误或者我没有找到发送 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 友好,或者是否有 another/better 方法从 NSArray 到 NULL 终止CFStringRef *
试试这个:
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);
没有核心 Foundation/Cocoa 内存管理问题,因为 CFArrayGetValues()
不给您返回值的所有权。