Мне нужен способ преобразовать 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
[ПРЕДУПРЕЖДЕНИЕ] Несовместимые типы указателей, отправляющие '__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 с нулевым завершением *