- 当我们用类似以下代码测试retainCount的时候,发现输出的并不是0.
@autoreleasepool
{
NSObject *obj = [[NSObject alloc] init];
[obj release];
NSLog(@"retainCount is %lu", obj.retainCount);
}
首先,以上代码是错误的写法。输出之前,对象的内存已经被释放,若内存被使用,这条语句就有可能使程序崩溃。
对于输出1的理解:系统知晓对象该被回收了,retainCount的值是否减1都没有必要了,不减1,减少了一次内存写操作,从而加速了内存的回收。 - 循环引用。
当2个或2个以上对象,彼此引用,形成环,这种现象叫循环引用。如下图:
出现了循环引用,将会导致环上的对象都无法释放空间。白白浪费内存。解决循环引用的问题主要有2种方式:
*在适当的位置断开一方的引用。它依赖于程序员有能力发现循环引用。
*使用若引用。弱引用也持有对象,但不会增加引用计数。这样就避免了环的产生。 - Core Foundation对象的内存管理
*Core Foundation是一个纯C语言编写的库,Foundation库是在其基础上发展起来的。
*IOS中允许两个框架对象之间的转换。
CFStringRef aCFString = (CFStringRef)aNSString;
NSString aNSString = (NSString )aCFString;
ARC可以帮我们管理Foundation框架中的对象,但是当使用到Core Foundation框架中的对象时,ARC就无能为力了。我们需要清除的是:对象转换后,谁来释放内存。
*MRC下,对象在转换使用后,手动释放掉就好。// NSString -> CFStringRef
NSString *nsStr1 = [NSString stringWithFormat:@"%d", 12345];
CFStringRef cfStr1 = (CFStringRef)nsStr1;
NSLog(@"%@", cfStr1);
CFRelease(cfStr1);
// CFStringRef -> NSString
CFStringRef cfStr2 = CFStringCreateWithCString(kCFAllocatorDefault, "12345", kCFStringEncodingUTF8);
NSString nsStr2 = (NSString )cfStr2;
NSLog(@"%@", nsStr2);
[nsStr2 release];
*ARC下,我们无法手动管理,但是要告诉转换后,对象的所有权归ARC还是我们自己。
__bridge 不改变对象的所有权,只是转换而已。
__bridge_retained(CFBridgingRetain) 解除ARC的所有权。
__bridge_transfer(CFBridgingRelease) 给予ARC的所有权。// NSString -> CFStringRef,当然不改变所有权最好,还是由ARC管理
NSString *nsStr1 = [NSString stringWithFormat:@"%d", 12345];
CFStringRef cfStr1 = (__bridge CFStringRef)nsStr1;
NSLog(@"%@", cfStr1);
CFRelease(cfStr1);
// CFStringRef -> NSString,交给ARC多方便
CFStringRef cfStr2 = CFStringCreateWithCString(kCFAllocatorDefault, "12345", kCFStringEncodingUTF8);
NSString nsStr2 = (__bridge_transfer NSString )cfStr2;
NSLog(@"%@", nsStr2); - 未完待续…
关于内存管理的一些小问题
最新推荐文章于 2024-08-07 22:39:33 发布