首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

AutoreleasePool从入门到放弃(8)

AutoreleasePool从入门到放弃(8)

原本的代码被转换成:

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        
        id temp = objc_retainAutoreleasedReturnValue([ViewController viewController]);
        ViewController *obj = temp
    }
     
    + (instancetype)viewController {
        
        ViewController *obj = [[ViewController alloc] init];
        
        return objc_autoreleaseReturnValue(obj);
    }

我们再看看objc_retainAutoreleasedReturnValue和objc_autoreleaseReturnValue的具体实现
objc_autoreleaseReturnValue(id obj)

    id objc_autoreleaseReturnValue(id obj)
    {
        if (prepareOptimizedReturn(ReturnAtPlus1)) return obj;
     
        return objc_autorelease(obj);
    }

根据函数调用列表判断是否走优化流程,如果autorelease后紧接着调用objc_retainAutoreleasedReturnValue就直接返回对象,否则正常进行入池操作。
prepareOptimizedReturn(ReturnDisposition disposition)

    static ALWAYS_INLINE bool prepareOptimizedReturn(ReturnDisposition disposition)
    {
        assert(getReturnDisposition() == ReturnAtPlus0);
     
        if (callerAcceptsOptimizedReturn(__builtin_return_address(0))) {
            if (disposition) setReturnDisposition(disposition);
            return true;
        }
     
        return false;
    }

函数callerAcceptsOptimizedReturn根据__builtin_return_address(0)获取到调用方的函数地址,然后通过地址列表进行后续函数调用的判断。如果后续调用了objc_retainAutoreleasedReturnValue则设置优化标志位
objc_retainAutoreleasedReturnValue(id obj)

    id objc_retainAutoreleasedReturnValue(id obj)
    {
        if (acceptOptimizedReturn() == ReturnAtPlus1) return obj;
     
        return objc_retain(obj);
    }

而该函数会根据prepareOptimizedReturn(ReturnAtPlus1)函数之前的优化标志位来判断是否需要对对象进行retain操作

文章最开始时也有使用调试函数分别打印下外部变量持有时和无外部变量持有时的池内对象的截图,可以用来验证上述TLS结论的正确性。(外部变量持有时会调用objc_retainAutoreleasedReturnValue,同学们通过可以去除外部变量持有后的汇编代码验证)
返回列表