• 【iOS】Tagged Pointer


    Tagged Pointer

    内存布局

    在这里插入图片描述

    • 代码段:编译之后的代码
    • 数据段
      • 字符串常量:比如NSString *str = @“123”
      • 已初始化数据:已初始化的全局变量、静态变量等
      • 未初始化数据:未初始化的全局变量、静态变量等
    • 堆:通过alloc、malloc、calloc等动态分配的空间,分配的内存空间地址越来越大-
    • 栈:函数调用开销,比如局部变量。分配的内存空间地址越来越小

    Tagged Pointer

    • 从64bit开始,iOS引入了Tagged Pointer技术,用于优化NSNumber、NSDate、NSString等小对象的存储
    • 在没有使用Tagged Pointer之前, NSNumber等对象需要动态分配内存、维护引用计数等,NSNumber指针存储的是堆中NSNumber对象的地址值
    • 使用Tagged Pointer之后,NSNumber指针里面存储的数据变成了:Tag + Data,也就是将数据直接存储在了指针中
    • 当指针不够存储数据时,才会使用动态分配内存的方式来存储数据
    • objc_msgSend能识别Tagged Pointer比如NSNumber的intValue方法,直接从指针提取数据,节省了以前的调用开销

    在小对象的时候, 使用Tagged Pointer,NSNumber指针里面存储的数据变成了:Tag + Data,也就是将数据直接存储在了指针中,不在需要存取来获取值了。

    我们分别打印abcdefghijk和abc字符串的类型。

    NSString *str1 = [NSString stringWithFormat:@“abc”];
    NSString *str2 = [NSString stringWithFormat:@“abcdefghijk”];
    NSLog(@“\n[str1 class]=%@\n[str2 class]=%@”,[str1 class],[str2 class]);

    打印结果:
    在这里插入图片描述

    根据打印发现str1是NSTaggedPointerString类型,是不通过set方法找对象的。

    我们也可以在源码中找到相关实现,

      1. 在NSObject.mm中查找retain方法的实现
    - (id)retain {
    	return ((id)self)->rootRetain();
    }
    
      1. 点击进入rootRetain方法,我们可以在里面找到:
        if (isTaggedPointer())
        return (id)this;
        也就是说如果是TaggedPointer类型,直接返回,不需要根据指针查找。

    判断是否是TaggedPointer

    我们点击isTaggedPointer方法

    _objc_isTaggedPointer(const void * _Nullable ptr)
    {
    return ((uintptr_t)ptr & _OBJC_TAG_MASK) == _OBJC_TAG_MASK;
    }

    • define _OBJC_TAG_MASK 1UL
    #if TARGET_OS_OSX && __x86_64__
    #   define OBJC_MSB_TAGGED_POINTERS 0
    #else
    #   define OBJC_MSB_TAGGED_POINTERS 1
    #endif
    
    
    #if OBJC_MSB_TAGGED_POINTERS
    #   define _OBJC_TAG_MASK (1UL<<63)
    #else
    #   define _OBJC_TAG_MASK 1UL
    #endif
    

    在判断是否是TaggedPointer的时候,在iOS平台和MAC平台还是不太一样的

    1、iOS平台,需要把1向左移动63位,也就是最高有效位是1(第64bit)
    2、在Mac平台,最低有效位是1

    面试题

    1. 什么是Tagged Pointer?
      答:Tagged Pointer是一种优化技术,用于存储小对象(如NSNumber、NSDate和NSString)的值。与普通对象不同,Tagged Pointer直接将数据存储在指针本身,而不是存储在堆上的内存块。这种技术利用了64位指针的高位来存储类型信息和实际数据,从而避免了分配和释放内存的开销,提高了性能和效率。

    2. Tagged Pointer的工作原理是什么?
      答:
      Tagged Pointer的工作原理基于将指针的部分位 用作标记(tag)和数据存储。具体实现如下:

      1. 标记位(Tag Bits):在64位指针的高位部分,用若干位来存储标记信息。这些标记位用来区分不同类型的Tagged Pointer(如NSNumber、NSDate等)。
      2. 数据位(Data Bits):在剩余的位中直接存储实际数据。例如,对于NSNumber,可以直接存储整数值或浮点数值。
      3. 类型检测:在需要时,通过检测指针的高位标记,判断该指针是否是Tagged Pointer以及它的类型。
    3. 如果检测一个指针是否是Tagged Pointer?
      答:
      检测一个指针是否是Tagged Pointer,可以通过检查指针的高位标记。具体实现方式因不同版本的Objective-C运行时而异,但常见的方式是检查指针是否设置了某些特定位。例如,在64位系统上,如果指针的最高位为1,则该指针可能是Tagged Pointer。代码示例如下:

    BOOL isTaggedPointer(id pointer) {
    return ((uintptr_t)pointer & _OBJC_TAG_MASK) != 0;
    }
    其中,_OBJC_TAG_MASK是用于检测Tagged Pointer的掩码。

    1. 给出一个Tagged Pointer NSNumber的示例,并解释其内部结构

    假设我们有一个Tagged Pointer类型的NSNumber对象,其内部结构可能如下:

    • 标记位:在指针的高位,用于标记该指针是Tagged Pointer以及它的类型(例如,NSNumber)。
    • 数据位:在指针的低位,存储实际的数值数据。

    例如,假设一个64位指针的结构如下:

    [63 ... 60] [59 ... 4] [3 ... 0]
      标记位       数据位    类型标记
    

    假设标记位为0b1110(表示NSNumber),类型标记为0b0001(表示整数类型),数据位为0b0000000000000000000000000000000000000000000000000000000000001101(表示整数13)。则这个Tagged Pointer的值表示一个NSNumber对象,其数值为13。

    怎么理解这个?
    这个比特位分布,和之前介绍的 isa_t 结构有些不同。这个新的比特位分布是 Objective-C 运行时系统中另一种优化技术 - “Packed Tagged Pointer”。

    下面我来解释一下这个结构的每个部分:

    [63 … 60] 标记位 (4 bits):
    这 4 个比特位用于标识这是一个 Packed Tagged Pointer,而不是普通的 isa 指针。
    它们会被设置为一个特殊的标记值,用于在运行时快速识别这种指针。
    [59 … 4] 数据位 (56 bits):
    这 56 个比特位用于存储对象的数值信息和类信息。
    具体的编码方式取决于对象的类型。
    [3 … 0] 类型标记 (4 bits):
    这 4 个比特位用于标识对象的具体类型,比如整数、浮点数、字符串等。

    运行时系统会根据这个类型标记来解析存储在数据位中的实际值。
    与之前介绍的 Tagged Pointer 相比,这种 Packed Tagged Pointer 的优势是能够存储更多的数据信息,提高了存储密度。

  • 相关阅读:
    gdb: coredump文件打开时提示 is truncated: expected core file size >= 1000, found: 500
    PIC16C程序调用汇编程序的问题
    关于在网上拉取项目,yarn后使用不了的,解决办法
    Android学习笔记 74. 调试程序
    @ConfigurationProperties和@Value的区别
    XP电源维修fleXPower电源X7-2J2J2P-120018系列详解
    基于电商平台的商品的关键词文本匹配任务 有代码有数据
    Web大学生网页作业成品:基于html制作中国科技发展网站设计题材【航天之路7页】HTML+CSS+JavaScript
    hrbust《程序设计基础》实践3
    Java IDEA controller导出CSV,excel
  • 原文地址:https://blog.csdn.net/cheng_lin0201/article/details/140964028