ARC:__bridge与__bridge_retained使用contextInfo测试用例

Ste*_*veo 5 memory-management objective-c retaincount automatic-ref-counting toll-free-bridging

考虑这个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;
}
Run Code Online (Sandbox Code Playgroud)

问题:在第7行,应该__bridge使用,或者__bridge_retained,或者无关紧要,或者选择是否依赖于字符串的保留计数(即,是否显式分配字符串与是否通过类初始化程序自动释放+[NSString stringWithString:]?

Mar*_*n R 11

一般来说,它是

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

// void * to object:
NSString *s = (__bridge NSString *)context;
Run Code Online (Sandbox Code Playgroud)

要么

// 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;
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,没有所有权转移,因此只要工作表处于活动状态,主程序 就必须对该对象进行强有力的引用.

在第二种情况下,在创建工作表时保留对象,并在sheetDidEnd:方法中释放.主程序不需要强有力的参考,因此这是安全的方法.

  • 第三种情况:设置上下文时使用__bridge_retained或CFBridgingRetain(),但在使用上下文时使用普通__bridge.当上下文应该永远存在但是没有其他方便的地方存储对它的强引用时使用. (3认同)