ARC 内存管理:
注意三点:
一: 不要出现循环引用
二: 如果出现 Core Foundation 对象(如: CFStringRef, CTFontRef)需要使用
CFRetain(对象)、 CFRelease(对象)来管理。 另外可以通过 桥接,
桥接的三种方式
__bridge: 只做类型转换,不修改相关对象的引用计数,原来的 Core Foundation 对象在不用时,需要 CFRelease;
__bridge_retained:类型转换后,引用计数加1,对象不用时,需要 CFRelease;
//等价于 CFBridgingRetain 详情看下面代码
__bridge_transfer: 类型转换后,该对象的引用计数交给 ARC 管理,对象不用时,不需要 CFRelease; //等价于 CFBridgingRelease 详情看下面代码
三:出现内存警告时,即时清除内存缓存。有的对象在不用时,可手动设置为 nil
__bridge:不涉及对象所有关系改变
__bridge_retained:解除 ARC 所有权
__bridge_transfer:给予 ARC 所有权
#pragma mark: 详解:
//OC -> 非 OC 对象
//代码1:不改变 所有权
CFStringRef s1 = (__bridge CFStringRef)([[NSString alloc] initWithFormat:@"Hello, %d!", 1]);
NSLog(@"%@", s1);
__bridge:不涉及对象所有权的改变:所以 s1 也是被 ARC 管理的。
如果后面加上CFRelease(s1);程序崩溃,因为这块内存还是归ARC管的,这样会过度释放。
//代码2:解除 ARC 所有权
CFStringRef s2 = (__bridge_retained CFStringRef)[[NSString alloc] initWithFormat:@”Hello, %d!”, 2];
//CFStringRef s2 = CFBridgingRetain([[NSString alloc] initWithFormat:@"Hello, %d!", 2]);
NSLog(@"%@", s2);
CFRelease(s2); //释放 s2
__bridge_retained:解除 ARC 所有权
这种情况下,对象的所有权交给CF对象了。就需要加上CFRelease(s2);进行释放,否则会产生泄露。
//代码3:OC -> 非OC 时,不能使用 __bridge_transfer
CFStringRef s3 = (__bridge_transfer CFStringRef)[[NSString alloc] initWithFormat:@"Hello, %d!", 3]; // 这行代码编译时会报错,提示修改
//非OC -> OC
//代码1:不改变 所有权
CFUUIDRef uu1 = CFUUIDCreate(NULL);
CFStringRef s1 = CFUUIDCreateString(NULL, uu1);
CFRelease(uu1);
NSString *str1 = (__bridge NSString *)(s1);
NSLog(@"%@", str1);
CFRelease(s1); //释放
//代码2:给予 ARC 所有权
CFUUIDRef uu2 = CFUUIDCreate(NULL);
CFStringRef s2 = CFUUIDCreateString(NULL, uu2);
CFRelease(uu2);
NSString *str2 = (__bridge_transfer NSString *)(s2);
//NSString *str2 = (CFBridgingRelease)(s2);
NSLog(@"%@", str2);
//CFRelease(s2); //调用CFRelease(s2);会造成过度释放。程序不一定崩溃,
//跟 uu2的释放时机有关,程序不崩溃时,也可能根编译器的优化有关吗?
//代码3:
NSString *str2 = (__bridge_retained NSString *)(s2); //报错,提示修改
//在每个需要桥接的地方,编译器器都会给提示。OC -> 非OC,非OC -> OC,都有两种桥接方式可选
//编译期内存检查
//点击 product -> Analyze 选择 这个编译模式, 可检查是否有内存泄露
//Analyze快捷键: Command + shift + B
//运行时内存检查: Instruments工具中的 Leaks
//点击 product -> Profile -> Leaks 可检查运行时的 内存泄露
//Instruments快捷键:Command + I
//检查内存泄露的博客
//http://blog.youkuaiyun.com/totogo2010/article/details/8233565