0

NSArrayをDADiskMountWithArgumentsの引数オプションと互換性のあるヌル終了リストに変換する方法が必要です。

ドキュメントでは、引数オプションがタイプの「ヌル終了リスト」になるように指定していますCFStringRef arguments[]

引数とともにNSArrayを渡したい Mount メソッドを作成しました。このメソッドでは、 NSArrayを CFStringRef * に変換する必要があります。

私は自分で試してみましたが、常にARCで問題が発生し、これを行う良い方法をまだ見つけることができませんでした.

インスピレーションを得るために、GitHub のプロジェクト Disk-Arbitrator 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));

次のエラー メッセージが表示されます。

ARC では、Objective-C 以外のポインター型 'void *' から '__strong id *' への暗黙的な変換は許可されていません

明示的な所有権のない非 const 型 '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 *' への暗黙的な変換は許可されていません

[警告] '__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 __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から NULL で終了する CFStringRef を取得するための別の/より良い方法があるかということです *

4

1 に答える 1