Board logo

标题: AutoreleasePool从入门到放弃(8) [打印本页]

作者: look_w    时间: 2019-3-8 19:46     标题: 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,同学们通过可以去除外部变量持有后的汇编代码验证)




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0