关于内存管理的一些小问题

  1. 当我们用类似以下代码测试retainCount的时候,发现输出的并不是0.
    @autoreleasepool 
    {
    NSObject *obj = [[NSObject alloc] init];
    [obj release];
    NSLog(@"retainCount is %lu", obj.retainCount);
    }

    首先,以上代码是错误的写法。输出之前,对象的内存已经被释放,若内存被使用,这条语句就有可能使程序崩溃。
    对于输出1的理解:系统知晓对象该被回收了,retainCount的值是否减1都没有必要了,不减1,减少了一次内存写操作,从而加速了内存的回收。
  2. 循环引用。
    当2个或2个以上对象,彼此引用,形成环,这种现象叫循环引用。如下图:
    出现了循环引用,将会导致环上的对象都无法释放空间。白白浪费内存。解决循环引用的问题主要有2种方式:
    *在适当的位置断开一方的引用。它依赖于程序员有能力发现循环引用。
    *使用若引用。弱引用也持有对象,但不会增加引用计数。这样就避免了环的产生。
  3. 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);
  4. 未完待续…
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值