zoukankan      html  css  js  c++  java
  • ARC有效时,id和void*的显式转换

    在ARC有效的情况下编译源代码,必须遵守一定的规则,其中之一就是“id”和“void *”需要显式转换。

    在ARC无效时,像下面的代码这样进行id变量和void*变量进行强制转换是没有问题的:

        @autoreleasepool {
            
            id obj0 = [[NSObject alloc] init];
            
            void* ptr = obj0;
            
            id obj1 = ptr;
            
            NSLog(@"obj retain count:%zi", [obj1 retainCount]);
            
            [obj1 release];
            
            //_objc_autoreleasePoolPrint();
        }

    但是这部分代码在ARC有效时会引起编译错误:

            ARC有效的情况下需要遵循的另一条规则是:不能使用retain/release/retainCount/autorelease。

            id类型或者对象型变量赋值给void *或者逆向赋值时(id类型和void*类型相互转换)需要进行显式的转换。如果只是单纯的赋值,可以使用“__bridge”进行显示转换。则上面的代码可以这项修改:

        @autoreleasepool {
            
            id obj0 = [[NSObject alloc] init];
            
            void* ptr = (__bridge void*)obj0;
            
            id obj1 = (__bridge id)ptr;
            
            //_objc_autoreleasePoolPrint();
        }

            但是转换为void *的__bridge转换安全性比较低,如果管理时不注意赋值对象的所有者,很可能会因悬垂指针而导致程序崩溃。

            为了补充__bridge转换的不足,还有另外两种转换,分别是“__bridge_retained”转换和“__bridge_transfer”转换。修改后的代码如下(__bridge_retained转换):

    id obj0 = [[NSObject alloc] init];
            
     void* ptr = (__bridge_retained void*)obj0;

            __bridge_retained转换可使要转换赋值的变量也持有所赋值的对象,在ARC无效时能达到同样效果的代码如下:

            id obj0 = [[NSObject alloc] init];
            
            void* ptr = obj0;
            [(id)ptr retain];
            
            NSLog(@"obj retain count:%zi", [obj0 retainCount]); //obj retain count:2

            下面说下__bridge_transfer转换,__bridge_transfer转换提供与__bridge_retained转换相反的操作,被转换的变量所持有的对象在该变量被赋值给转换目标后随之释放。__bridge_transfer转换代码如下:

            id obj0 = [[NSObject alloc] init];
            
            void* ptr = (__bridge_retained void *)obj0;
            
            id obj1 = (__bridge_transfer id)ptr;

            在ARC无效时与__bridge_transfer转换有同样效果的代码如下:

            id obj0 = [[NSObject alloc] init];
            
            void* ptr = obj0;
            
            //等同__bridge_transfer
            id obj1 = ptr;
            [obj1 retain];
            [(id)ptr release];
            
            NSLog(@"obj retain count:%zi", [obj0 retainCount]); //obj retain count:1
  • 相关阅读:
    「BZOJ 1000」A+B Problem
    「HNOI 2008」越狱
    蓝桥杯 拼音字母
    蓝桥杯 抽签
    蓝桥杯 快速排序
    [蓝桥杯] 最大比例
    [蓝桥杯] 交换瓶子
    [蓝桥杯] 四平方和
    [蓝桥杯] 剪邮票
    [蓝桥杯] 方格填数
  • 原文地址:https://www.cnblogs.com/arthas/p/4655143.html
Copyright © 2011-2022 走看看