iOS开发笔记

__bride、__bride_transfer和__bride

2019-08-08  本文已影响0人  祥子_HelloWorld

在上一篇里讲到内存泄漏的检测,有一处内存泄露是由于CoreFoundation创建的对象没有释放掉,在开发中Foundation和CoreFoundation框架里的对象需要转换才能用。

一、ARC和Foundation、CoreFoundation

和它一样的还有__bride_transfer和__bride_retain,那么他们之间有什么关系和区别呢?在讲这个之前我们先看一下ARC和Foundation、CoreFoundation框架之间的关系:

二、__bride、__bride_transfer和__bride_retain的区别和作用

所以,在非ARC下两者互转都是需要手动管理内存的,我们重点关注的是在ARC下转换注意的地方。那么下面就是在ARC下,__bride、__bride_transfer和__bride_retain的区别和作用:

三、用法实例

接上一篇的一个内存泄露的例子,下面代码中C语言创建的两个对象没有释放:

+ (NSString *)createUUID
{
    CFUUIDRef uuidRef = CFUUIDCreate(NULL);
    CFStringRef uuidStrRef = CFUUIDCreateString(NULL, uuidRef);
    NSString *uuidStr = [NSString stringWithFormat:@"%@",uuidStrRef];   
    return uuidStr;
}

在上一篇中我们给出的解决办法,也是最直观的办法是手动释放对象的内存:

+ (NSString *)createUUID
{
    CFUUIDRef uuidRef = CFUUIDCreate(NULL);
    CFStringRef uuidStrRef = CFUUIDCreateString(NULL, uuidRef);
    NSString *uuidStr = [NSString stringWithFormat:@"%@",uuidStrRef];

    CFRelease(uuidRef);
    CFRelease(uuidStrRef);
    
    return uuidStr;
}

其实在上面提到的__bride_transfer和__bride_retain也可以解决类似的内存管理的问题,比如下面这种改法:

+ (NSString *)createUUID
{
    CFUUIDRef uuidRef = CFUUIDCreate(NULL);
    CFStringRef uuidStrRef = CFUUIDCreateString(NULL, uuidRef);
    
    NSString *uuidStr = (__bridge_transfer NSString *)uuidStrRef;

    return uuidStr;
}

__bridge_transfer用在将CoreFoundation对象转换成Foundation对象,用于进行内存管理权移交,手动变自动,所以创建的对象交给了ARC去管理,就不用手动释放了。

四、三种示例
/* ARC管理的Foundation对象 */
        NSString *s1 = @"string";
        //转换后依然由ARC管理释放
        CFStringRef cfstring = (__bridge CFStringRef)s1;
        //开发者手动管理的CoreFoundation对象,需要手动释放
        CFStringRef s2 = CFStringCreateWithCString(NULL, "string", kCFStringEncodingASCII);
        //转换后依然需要开发者手动管理释放
        NSString *fstring = (__bridge NSString*)s2;
        //手动释放CFRelease(s2);
        
        
 /* 转换后改由ARC管理对象的释放,不用担心内存泄露 */
        NSString *fstring1 = (__bridge_transfer NSString*)s2;
        //等效于
        //NSString *fstring1 = (NSString*)CFBridgingRelease(s2);
        
        
 /* 转换后ARC不再继续管理,需要手动释放 */
        CFStringRef cfstring1 = (__bridge_retained CFStringRef)s1;
        //等效于
        //CFStringRef cfstring1 = (CFStringRef)CFBridgingRetain(s1);

还有一篇iOS __bridge那些事讲的也很详细,可以参考一下。

上一篇下一篇

猜你喜欢

热点阅读