OC基础-Foundation对象 和 Core Foundation对象间的转换

  • Foundation框架是使用OC实现的
  • Core Foundation是使用C实现的
  • Foundation对象 和 Core Foundation对象间的转换:俗称桥接
  • ARC环境:使用桥接,共有三种桥接关键字
    • __bridge:可用于Foundation对象 和 Core Foundation对象间的相互转换
    • __bridge_retained:用于Foundation对象 转成 Core Foundation对象
    • __bridge_transfer:用于Core Foundation对象 转成 Foundation对象
  • Foundation对象 转成 Core Foundation对象
    • 使用__bridge桥接
      • 如果使用__bridge桥接,它仅仅是将strOC的地址给了strC, 并没有转移内存管理权,也就是说, 如果使用__bridge桥接, 那么如果strOC释放了,strC也不能再使用了
      • 如果是使用__bridge桥接,那么strC可以不用主动释放, 因为ARC环境会自动管理
       NSString *strOC = [NSString stringWithFormat:@"abcdefg"];
       // strC不用手动释放
       CFStringRef strC = (__bridge CFStringRef)strOC1;
       NSLog(@"%@ %@", strOC, strC);
      
    • 使用__bridge_retained桥接
      • 如果使用__bridge_retained桥接,它会将strOC的内存管理权转交给strC, 也就是说, 即便strOC被释放了, strC也可以使用
      • 如果是使用__bridge_retained桥接,那么strC必须自己手动释放,因为桥接的时候已经将对象的内存管理权转交给了strC,而C语言的东西不归ARC管理
      • __bridge_retained关键字等价于CFBridgingRetain函数
NSString *strOC = [NSString stringWithFormat:@"abcdefg"];
//    CFStringRef strC = (__bridge_retained CFStringRef)strOC;
CFStringRef strC = CFBridgingRetain(strOC);// 这一句, 就等同于上一句
CFRelease(strC);
  • Core Foundation对象 转成 Foundation对象

    • 使用__bridge桥接
      • 如果使用__bridge桥接,它仅仅是将strC的地址给了strOC, 并没有转移内存管理权,也就是说, 如果使用__bridge桥接, 那么如果strC释放了,strOC也不能再使用了
      • strC还需要手动释放
    CFStringRef strC = CFStringCreateWithCString(CFAllocatorGetDefault(), "12345678", kCFStringEncodingASCII);
    NSString *strOC = (__bridge NSString *)strC;
    CFRelease(strC);
    
    • 使用__bridge_transfer桥接
      • 如果使用__bridge_transfer桥接,它会将strC的内存管理权转交给strOC, 也就是说, 即便strC被释放了, strOC也可以使用
      • 如果使用__bridge_transfer桥接, 那么就不用手动释放strC`
      • __bridge_transfer关键字等价于CFBridgingRelease函数
    CFStringRef strC = CFStringCreateWithCString(CFAllocatorGetDefault(), "12345678", kCFStringEncodingASCII);
    //     NSString *strOC = (__bridge_transfer NSString *)strC;
    NSString *strOC = CFBridgingRelease(strC); // 这一句, 就等同于上一句
    
  • MRC环境: Foundation对象 和 Core Foundation对象间可以直接强转

-(void)bridgeInMRC
{
    // 将Foundation对象转换为Core Foundation对象,直接强制类型转换即可
    NSString *strOC1 = [NSString stringWithFormat:@"xxxxxx"];
    CFStringRef strC1 = (CFStringRef)strOC1;
    NSLog(@"%@ %@", strOC1, strC1);
    [strOC1 release];
    CFRelease(strC1);
    
    // 将Core Foundation对象转换为Foundation对象,直接强制类型转换即可
    CFStringRef strC2 = CFStringCreateWithCString(CFAllocatorGetDefault(), "12345678", kCFStringEncodingASCII);
    NSString *strOC2 = (NSString *)strC2;
    NSLog(@"%@ %@", strOC2, strC2);
    [strOC2 release];
    CFRelease(strC2);
}

你可能感兴趣的:(OC基础-Foundation对象 和 Core Foundation对象间的转换)