Конвертировать NSArray в CFStringRef *
Мне нужен способ конвертировать NSArray в нулевой завершенный список, совместимый с параметром аргументов DADiskMountWithArguments.
В документации указан параметр аргумента, который должен быть "завершенным нулевым списком" типа CFStringRef arguments[]
,
Я создал метод Mount, которому я хочу передать NSArray с аргументами, и в моем методе мне нужно преобразовать NSArray в CFStringRef *.
Я пробовал себя, но у меня всегда были проблемы с ARC, и я пока не смог найти хорошего способа сделать это.
Я посмотрел на проект Disk-Arbitrator в GitHub https://github.com/aburgh/Disk-Arbitrator/blob/master/Source/Disk.m для вдохновения, и создатель этого приложения использует этот метод:
- (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 *' в '__strong id *' запрещено с ARC
Указатель на неконстантный тип 'id' без явного владельца.
Чтобы исправить это, я пытаюсь сделать это:
id argv = (__bridge id)(calloc(args.count + 1, sizeof(id)));
Тогда эта строка:
[args getObjects:argv range:NSMakeRange(0, args.count)];
Выдает следующие ошибки:
[ОШИБКА] Неявное преобразование указателя 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". Итак, чтобы исправить это, я объявляю свой идентификатор как __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 __CFString **) запрещено с 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, или есть другой / лучший способ получить NSArray к CFStringRef с NULL-завершением *
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()
не дает вам права собственности на возвращаемые значения.