我已阅读有关__bridge
,_bridge_retain
和_bridge_transfer
的信息,并做了一些实验。但是输出与我的期望不一致。特别是,我有以下代码:
@interface ViewController ()
@property (nonatomic, strong) NSString *test;
@end
@implementation ViewController
CFStringRef cfString;
- (void)viewDidLoad
{
[super viewDidLoad];
self.test = @"123";
cfString = (__bridge CFStringRef)self.test;
self.test = nil;
}
- (void)viewDidAppear:(BOOL)animated
{
NSLog(@"%@", cfString);
NSLog(@"%@", self.test);
}
我希望程序崩溃,基于以下推理:_bridge
不会转移所有权,因此在将self.test
转换为cfString
时,没有retainCount增量。将self.test
设置为nil
后,ARC
将介入并取消分配字符串。因此释放了该部分内存,但cfString
仍然指向那里,导致指针访问异常。与我的推理相反,输出为123且为null,当然程序不会崩溃。
此外,如果我更换
self.test = nil;
与
CFRelease(cfString);
由于类似的推理,我预计程序也会崩溃。更奇怪的是输出现在是123和123.
任何人都可以详细说明原因吗?顺便说一句,所有权一词总是让我烦恼,一些解释将不胜感激。
答案 0 :(得分:2)
您的问题是您使用的是常量字符串。这被直接放入程序存储器中,因此尽管不应该引用,但引用仍然意外地保持有效。使用比常量字符串更不变的东西,你的程序会像你想象的那样制动。
答案 1 :(得分:1)
问题是您的示例基于文字NSString值。
在objective-C中,永远不会释放常量NSString(编译时已知的常量值)。实际上,他们的主要记忆管理方法如下:
+ (id)allocWithZone:(NSZone *)zone {
id _uniqueInstance = [self _singletonInstanceOfClass];
if( _uniqueInstance == nil )
_uniqueInstance = [super allocWithZone:zone];
return _uniqueInstance;
}
- (id)copyWithZone:(NSZone *)zone {
(void)zone;
return self;
}
- (id)retain {
return self;
}
- (NSUInteger)retainCount {
return NSUIntegerMax; // denotes an object that cannot be released
}
- (oneway void)release {
//do nothing
return;
}
- (id)autorelease {
return self;
}
如您所见,发布它们是不可能的。