5

次の ARC コードを検討してください。

- (void)main {
    NSString *s = [[NSString alloc] initWithString:@"s"];
    [NSApp beginSheet:sheet 
           modalForWindow:window 
           modalDelegate:self 
           didEndSelector:@selector(sheetDidEnd:returnCode:context:) 
           contextInfo:(__bridge void *)s
    ];
}

- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(NSInteger)returnCode context:(void *)context {
    NSString *s = (__bridge_transfer NSString *)context;
}

質問: 7 行目で、 を__bridge使用する必要がありますか、 または__bridge_retained、またはそれは問題ではありませんか、それとも文字列の保持カウント (つまり、文字列が明示的に割り当てられているか、 のようなクラス初期化子を介して自動解放されているか) に依存します+[NSString stringWithString:]か?

4

1 に答える 1

11

一般的には、次のいずれかです。

// Object to void *:
contextInfo:(__bridge void *)s

// void * to object:
NSString *s = (__bridge NSString *)context;

また

// Object to void *, retaining the object:
contextInfo:(__bridge_retained void *)s

// void * to object, transferring ownership.
// The object is released when s goes out of scope:
NSString *s = (__bridge_transfer NSString *)context;

最初のケースでは、所有権が譲渡されないため、シートがアクティブである限り、メイン プログラム はオブジェクトへの強力な参照を保持する必要があります。

2 番目のケースでは、オブジェクトはシートの作成時に保持され、sheetDidEnd:メソッドで解放されます。メイン プログラムが強い参照を保持する必要はないため、これは安全な方法です。

于 2013-12-30T15:36:12.767 に答える