副标题#e#
iOS答允Objective-C 和 Core Foundation 工具之间可以轻松的转换,拿 NSString 和 CFStringRef 来说,直接转换豪无压力:
CFStringRef aCFString = (CFStringRef)aNSString;
NSString *aNSString = (NSString *)aCFString;
针对内存打点问题,ARC 可以资助打点 Objective-C 工具, 可是不支持 Core Foundation 工具的打点,所以转换后要留意一个问题:谁来释放利用后的工具。 本文重点总结一下范例转换后的内存打点。
一、非ARC的内存打点
倘若不利用ARC,手动打点内存,思路较量清晰,利用完,release转换后的工具即可。
//NSString 转 CFStringRef CFStringRef aCFString = (CFStringRef) [[NSString alloc] initWithFormat:@"%@", string]; //... CFRelease(aCFString); //CFStringRef 转 NSString CFStringRef aCFString = CFStringCreateWithCString(kCFAllocatorDefault, bytes, NSUTF8StringEncoding); NSString *aNSString = (NSString *)aCFString; //... [aNSString release];
二、ARC下的内存打点
ARC的降生大大简化了我们针对内存打点的开拓事情,可是只支持打点 Objective-C 工具, 不支持 Core Foundation 工具。Core Foundation 工具必需利用CFRetain和CFRelease来举办内存打点。那么当利用Objective-C 和 Core Foundation 工具彼此转换的时候,必需让编译器知道,到底由谁来认真释放工具,是否交给ARC处理惩罚。只有正确的处理惩罚,才气制止内存泄漏和double free导致措施瓦解。
按照差异需求,有3种转换方法
__bridge (不改变工具所有权)__bridge_retained 可能 CFBridgingRetain() (清除 ARC 所有权)__bridge_transfer 可能 CFBridgingRelease() (给以 ARC 所有权)
1. __bridge_retained 可能 CFBridgingRetain()
__bridge_retained 可能 CFBridgingRetain() 将Objective-C工具转换为Core Foundation工具,把工具所有权桥接给Core Foundation工具,同时剥夺ARC的打点权,后续需要开拓者利用CFRelease可能相关要领手动来释放工具。
来看个例子:
- (void)viewDidLoad { [super viewDidLoad]; NSString *aNSString = [[NSString alloc]initWithFormat:@"test"]; CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString; (void)aCFString; //正确的做法应该执行CFRelease //CFRelease(aCFString); }
措施没有执行CFRelease,造成内存泄漏:
CFBridgingRetain() 是 __bridge_retained 的宏要领,下面两行代码等价:
CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString; CFStringRef aCFString = (CFStringRef) CFBridgingRetain(aNSString);
#p#副标题#e#
2. __bridge_transfer 可能 CFBridgingRelease()
__bridge_transfer 可能 CFBridgingRelease() 将非Objective-C工具转换为Objective-C工具,同时将工具的打点权交给ARC,开拓者无需手动打点内存。
接着上面谁人内存泄漏的例子,再转成OC工具交给ARC来打点内存,无需手动打点,也不会呈现内存泄漏:
- (void)viewDidLoad { [super viewDidLoad]; NSString *aNSString = [[NSString alloc]initWithFormat:@"test"]; CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString; aNSString = (__bridge_transfer NSString *)aCFString; }
CFBridgingRelease() 是__bridge_transfer的宏要领,下面两行代码等价:
aNSString = (__bridge_transfer NSString *)aCFString;
aNSString = (NSString *)CFBridgingRelease(aCFString);
3. __bridge
__bridge 只做范例转换,不改变工具所有权,是我们最常用的转换符。
从OC转CF,ARC打点内存:
- (void)viewDidLoad { [super viewDidLoad]; NSString *aNSString = [[NSString alloc]initWithFormat:@"test"]; CFStringRef aCFString = (__bridge CFStringRef)aNSString; (void)aCFString; }
从CF转OC,需要开拓者手动释放,不归ARC管:
- (void)viewDidLoad { [super viewDidLoad]; CFStringRef aCFString = CFStringCreateWithCString(NULL, "test", kCFStringEncodingASCII); NSString *aNSString = (__bridge NSString *)aCFString; (void)aNSString; CFRelease(aCFString); }
From:csdn博客 念茜