NSString *p5 = @"jasikar",nsstring对象的jasikar值存在哪里了呢?

以前问过大光一个问题 nsstring类型的对象的值存在哪里了呢?是否和person类一样有个属性name来存储"jasikar"呢?或像大光回答的p5指针指向的既是"jasikar"? 答案是否定的。搜索nsstring的帖子大多写了nsstring指向的是常量内存区,没有更具体的说明了。那今天碰巧想到了个问题解决方法。

先写结论:nsstring *p5 指向的是个对象,地址0x100002098 对象中只有一个isa_t  的isa指针(这里isa_t是一个union,被解析成不同成员,一个对象在没有属性的情况下最少占用16个字节,其中8个字节是isa指针,另外的8个字节是额外信息(还需查资料,自己不太清楚)

x/8xw 0x100002098    0x100002098: 0x9e1181d8 0x00007fff 0x000007c8 0x00000000

0x1000020a8: 0x00001dce 0x00000001 0x00000007 0x00000000

结论是jasikar 的指针存储在对象地址+0x10的地方0x1000020a8:0x00001dce 0x00000001


intmain(intargc,constchar* argv[]) {

    @autoreleasepool {

        NSString*p5 =@"jasikar";

        constchar* a =[p5 UTF8String];

        NSLog(@"a对应的字符串对应的字符常量区地址= %p",p5);


在Xcode中建立NSString *p5 = @"jasikar",通过追踪p5 的 UTF8String方法实现来解析nsstring 对象


(lldb) p ( char *)0x0000000100001dce

(char *) $1022 = 0x0000000100001dce "jasikar"

(lldb) p (objc_object * )0x100002098

(objc_object *) $1023 = 0x0000000100002098

(lldb) p *$1023

(objc_object) $1024 = {

  isa = 0x00007fff9e1181d8

}

(lldb) p (objc_class *)0x00007fff9e1181d8

(objc_class *) $1025 = 0x00007fff9e1181d8

(lldb) p *$1025

(objc_class) $1026 = {

  objc_object = {

    isa = 0x001dffff9e118189

  }

  superclass = __NSCFString

  cache = {

    _buckets = 0x0000000100f59f10

    _mask = 7

    _occupied = 6

  }

  bits = (bits = 4310790448)

}

(lldb) p $1025.data()

(class_rw_t *) $1027 = 0x0000000100f17130

  Fix-it applied, fixed expression was: 

    $1025->data()

(lldb) p *$1027

(class_rw_t) $1028 = {

  flags = 2148007936

  version = 0

  ro = 0x00007fff9e0faea0

  methods = {

    list_array_tt = {

       = {

        list = 0x00007fff9e0fadd8

        arrayAndFlag = 140735845215704

      }

    }

  }

  properties = {

    list_array_tt = {

       = {

        list = 0x00007fff9e0fae88

        arrayAndFlag = 140735845215880

      }

    }

  }

  protocols = {

    list_array_tt = {

       = {

        list = 0x00007fff9e0fad78

        arrayAndFlag = 140735845215608

      }

    }

  }

  firstSubclass = nil

  nextSiblingClass = nil

  demangledName = 0x0000000000000000

}

(lldb) p $1027.ro 

(const class_ro_t *) $1029 = 0x00007fff9e0faea0

  Fix-it applied, fixed expression was: 

    $1027->ro 

(lldb) p *$1029

(const class_ro_t) $1030 = {

  flags = 16

  instanceStart = 8

  instanceSize = 8

  reserved = 0

  ivarLayout = 0x0000000000000000

  name = 0x00007fff434a28e9 "__NSCFConstantString"

  baseMethodList = 0x00007fff9e0fadd8

  baseProtocols = 0x00007fff9e0fad78

  ivars = 0x0000000000000000

  weakIvarLayout = 0x0000000000000000

  baseProperties = 0x00007fff9e0fae88

}


这里是__NSCFConstantString类的内容。怎么也找不到"jasikar"在哪里。

设断点进入 UTF8String内部 这里是CoreFoundation 全是汇编写的。


UTF8String方法

跳过CFstringMtbl,进入CFStringGetCstringPtr函数,这是关键。


类似的函数

一点一点分析,传入的%rdi =0x10002098 %rsi =8000100 是上图贴的转换类型,实现的关键在下面这个代码



   0x7fff4307b8a0<+116>: movq  0x8(%r14), %rax    //r14=0x10002098 rax =0x7c8 

    0x7fff4307b8a4<+120>: testb  $0x8, %al.          //

    0x7fff4307b8a6 <+122>: je    0x7fff4307b9a0            ; <+372>//不跳

    0x7fff4307b8ac<+128>: movq  0x8(%r14), %rcx   //rcx =0x7c8

    0x7fff4307b8b0<+132>: leaq  0x10(%r14), %rax. //rax =0x1000020a8   

 0x7fff4307b8b4<+136>: testb  $0x60, %cl

    0x7fff4307b8b7 <+139>: je    0x7fff4307b949            ; <+285>

    0x7fff4307b8bd<+145>: movq  (%rax), %rcx.     // rcx=0x100001dce

//这里能看到 rax是 对象1000020a8 +0x10 即是对象地址处+16个字节处存储了"jasikar"


看p (char *)0x100001dce

0x7fff4307b8c0 <+148>: jmp    0x7fff4307b95d            ; <+305>

 0x7fff4307b95d<+305>: movq  0x8(%r14), %rax

    0x7fff4307b961<+309>: shrl  $0x2, %eax

->  0x7fff4307b964<+312>: andl  $0x1, %eax

    0x7fff4307b967<+315>: addq  %rcx, %rax

    0x7fff4307b96a <+318>: jmp    0x7fff4307b9a2            ; <+374>

  0x7fff4307b9a2 <+374>: popq  %rbx

    0x7fff4307b9a3<+375>: popq  %r14

    0x7fff4307b9a5<+377>: popq  %rbp

    0x7fff4307b9a6 <+378>: retq   

到这里就结束了 可以看到rax unsigned long 0x0000000100001dce,最返回的是"jasikar"所在地址。 本文到此结束了。结论是jasikar 的指针存储在对象地址+0x10的地方。。

你可能感兴趣的:(NSString *p5 = @"jasikar",nsstring对象的jasikar值存在哪里了呢?)