一·动态调试
断点处可以看见,x0 objc_alloc_init调用方法,从x8取出,既看x8和x0寄存器。
使用LLDB regist read x8 可以得到x8保存的是类对象Person
add x8 ,x8 ,#0x538
ldr x0, [x8]
这句汇编代码说明了:Person对象调用alloc方法
0x1049d5d88 adrp x8 ,8
忽略后三位0x1049d5 5 8=13
得到0x1049dd 补上0x538=0x1049dd538
p (SEL)0x1049dd538 得到方法
此时内存中还没有初始化对象
直到这句汇编
str x0,[sp,#0x8]
然后LLDB调试得到 po p 就可以得到对象
二·objc_storeStrong
疑问谁调用了objc_storeStrong
依旧使用动态调试查看x0 的值
代码解读:
add x8 ,sp,#0x8
反映到代码上就是 x8 = &p
寄存器x8 保存sp偏移8个字节的栈内存地址
str x0,[sp,#0x8]
把[[Person alloc] init]的返回值给到sp在栈空间偏移8个字节,然后返回该对象的地址给x0
反映到代码上就是 Person *p =[[Person alloc] init]
所以po p可以得到对象.
mov x0, x8
mov x8,#0x0
此时调用的参数有结果了
objc_storeStrong(x0,x8) ->objc_storeStrong(&p,nil)
然后栈平衡汇编结束
三·Runtime
objc_storeStrong函数在objc4-750苹果官网处开源
objc_storeStrong(id *location,id obj){
id prev = *location; // p = *&p
id (obj==prev){ //如果对象是空返回
return;
}
objc_retain(obj); //retain nil
*location = obj; //p = nil 非ARC下需要手动管理内存
objc_release(prev); //objc_release(p)
}
id本身就是OC对象,是一个指针类型,泛型,any类。id * 指向oc对象的一个指针
这句ARC函数做了这几件事:
1.把p=nil 指向nil
2.release 原来p指向的堆空间