<h3 id="arc">ARC</h3>
ARC能够解决iOS开发中90%的内存管理问题,但是另外还有10%的内存管理是需要手动管理的,主要就是与底层Core Foundation对象交互的部分,因为底层Core Foundation对象由于不在ARC的管理下。
使用ARC需要额外注意的两个问题:
1.过度使用block产生的循环引用问题。
2.底层Core Foundation对象需要手动进行内存管理。
<h3 id="corefoundation">Core Foundation对象的内存管理</h3>
底层的Core Foundation对象的创建,大多数以XxxCreateWithXxx这样的方式创建,例如:
//创建一个CFStringRef对象
CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault,"hello world",kCFStringEncodingUTF8);
或者
//设置字间距
+ (NSAttributedString *)setLabelAttributeString:(NSString*)labelText withCharactorSpace:(CGFloat)charactorSpace{
NSMutableAttributedString *string =[[NSMutableAttributedString alloc]initWithString:labelText];
long number = charactorSpace;
CFNumberRef num = CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt8Type,&number);
[string addAttribute:(id)kCTKernAttributeName value:(__bridge id)num range:NSMakeRange(0,[string length])];
CFRelease(num);
return string;
}
对于这种对象的修改和释放,需要相应的使用CFRetain和CFRelease。
除此之外,还有另外一个问题需要解决。在ARC下,我们有时需要将一个Core Foundation对象转换成Objective-C对象,这个时候我们需要告诉编译器,转换过程中的引用计数如何调整。这就引入了与bridge相关的关键字:
-
__bridge
:只做类型转换,不修改相关对象的引用计数,原来的Core Foundation对象在不用时,需要调用CFRelease方法。 -
__bridge_retained
:类型转换后,将相关对象的引用计数+1,原来的Core Foundation对象在不用时,需要调用CFRelease方法。 -
__bridge_transfer
:类型转换后,将该对象的引用计数交给ARC管理,Core Foundation对象在不用时,不再需要调用CFRelease方法。
我们根据业务逻辑,合理使用上面三种转换关键字,就可以解决Core Foundation对象与Objc对象相互转换的问题了。