iOS - Tagged Pointer

1. 基本结构

objectivec 复制代码
// Tagged Pointer 的内存布局
union TaggedPointer {
    uintptr_t bits;  // 完整的指针值
    struct {
        uintptr_t data     : 60;  // 数据部分
        uintptr_t tag      : 4;   // 类型标记
    };
    
    // 扩展类型
    struct {
        uintptr_t extData  : 52;  // 扩展数据
        uintptr_t extTag   : 8;   // 扩展标记
        uintptr_t isExt    : 4;   // 是否是扩展类型
    };
};

2. 类型判断

objectivec 复制代码
// 判断是否是 Tagged Pointer
static inline bool 
isTaggedPointer(const void *ptr) {
    return ((uintptr_t)ptr & _OBJC_TAG_MASK) == _OBJC_TAG_MASK;
}

// 获取类型标记
static inline uintptr_t 
getTaggedPointerTag(const void *ptr) {
    return ((uintptr_t)ptr >> _OBJC_TAG_SLOT_SHIFT) & _OBJC_TAG_MASK;
}

3. 支持的数据类型

3.1 基本类型

objectivec 复制代码
// NSNumber 的 Tagged Pointer 实现
+ (NSNumber *)numberWithInt:(int)value {
    // 如果值在 Tagged Pointer 范围内
    if (value >= MIN_TAGGED_INT && value <= MAX_TAGGED_INT) {
        uintptr_t tagged = ((uintptr_t)value << 4) | NSNumberTag;
        return (__bridge id)(void *)tagged;
    }
    // 否则创建普通对象
    return [[NSNumber alloc] initWithInt:value];
}

3.2 字符串类型

objectivec 复制代码
// NSString 的 Tagged Pointer 实现
+ (NSString *)stringWithSmallString:(const char *)str {
    size_t length = strlen(str);
    if (length <= 7) {  // 可以用 Tagged Pointer 存储
        uintptr_t tagged = 0;
        for (size_t i = 0; i < length; i++) {
            tagged |= ((uintptr_t)str[i] << (i * 8));
        }
        tagged |= (NSStringTag << 60);  // 添加标记
        return (__bridge id)(void *)tagged;
    }
    return [[NSString alloc] initWithUTF8String:str];
}

4. 内存管理

4.1 引用计数

objectivec 复制代码
// Tagged Pointer 不需要引用计数
id objc_retain(id obj) {
    if (isTaggedPointer(obj)) return obj;
    return obj->retain();
}

void objc_release(id obj) {
    if (isTaggedPointer(obj)) return;
    return obj->release();
}

4.2 内存优化

objectivec 复制代码
// 直接存储数据,无需额外内存分配
+ (instancetype)optimizedNumberWithInt:(int)value {
    if (canBeTaggedPointer(value)) {
        return makeTaggedPointer(value);
    }
    return [self newNumberWithInt:value];
}

5. 消息发送

objectivec 复制代码
id objc_msgSend_tagged(id self, SEL _cmd, ...) {
    // 1. 获取类型标记
    uintptr_t tag = getTaggedPointerTag(self);
    
    // 2. 获取对应的类
    Class cls = objc_getTaggedPointerClass(tag);
    
    // 3. 查找方法
    IMP imp = lookUpImpOrForward(cls, _cmd);
    
    // 4. 调用方法
    return imp(self, _cmd, ...);
}

6. 性能优化

6.1 空间优化

objectivec 复制代码
// 普通对象
struct NSNumber {
    Class isa;
    int value;      // 至少需要 16 字节
};

// Tagged Pointer
// 直接使用指针存储值,只需要 8 字节
uintptr_t taggedNumber = (value << 4) | tag;

6.2 时间优化

objectivec 复制代码
// 普通对象访问
int getValue(NSNumber *num) {
    // 1. 解引用 isa
    // 2. 解引用获取值
    return num->_value;
}

// Tagged Pointer 访问
int getTaggedValue(NSNumber *num) {
    // 直接从指针中提取值
    return (uintptr_t)num >> 4;
}

7. 限制和注意事项

7.1 大小限制

objectivec 复制代码
// 数据大小限制
#define TAGGED_POINTER_MASK  0xF000000000000000
#define TAGGED_POINTER_DATA  0x0FFFFFFFFFFFFFFF

bool canBeTagged(size_t size) {
    // 60位数据位的限制
    return size <= (sizeof(uintptr_t) * 8 - 4);
}

7.2 类型限制

objectivec 复制代码
// Tagged Pointer 支持的类型定义
static Class taggedPointerClasses[] = {
    [OBJC_TAG_NSAtom]            = NSAtom,              // 0
    [OBJC_TAG_NSString]          = NSString,            // 1
    [OBJC_TAG_NSNumber]          = NSNumber,            // 2
    [OBJC_TAG_NSIndexPath]       = NSIndexPath,         // 3
    [OBJC_TAG_NSManagedObjectID] = NSManagedObjectID,   // 4
    [OBJC_TAG_NSDate]            = NSDate,               // 5
    [OBJC_TAG_NSDateTS]          = NSDateTS,             // 6
    [OBJC_TAG_NSDecimalNumber]   = NSDecimalNumber       // 7
};

8. 实际应用

8.1 字符串优化

objectivec 复制代码
NSString *str1 = @"abc";     // 可能使用 Tagged Pointer
NSString *str2 = @"这是一个很长的字符串";  // 普通对象

Tagged Pointer 的优势:

  1. 减少内存分配
  2. 提高访问速度
  3. 减少引用计数操作
  4. 优化内存使用

这种优化对于小对象的处理特别有效,是一个重要的性能优化手段。

相关推荐
屑曦晨2 小时前
PKToolPicker工具栏图标错误模糊问题排查报告
ios
2501_915921433 小时前
详细解析,iOS 应用上架 App Store 的完整流程与指南
android·ios·小程序·https·uni-app·iphone·webview
2501_915106323 小时前
SwiftUI项目创建详解:使用Xcode从零开始创建第一个App项目
ide·vscode·ios·swiftui·个人开发·xcode·敏捷流程
9765033355 小时前
iOS 上架/审核 4.3a Cocos 2026最新方案解读
flutter·ios·swift·cocos2d·ios开发
2501_916007475 小时前
IDE 是什么?集成开发环境详解与 iOS 开发选型指南
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
梦想的颜色5 小时前
UniApp 四端对齐实战:iOS App / Android App / 小程序 / H5 兼容坑点与完整解决方案|AI 辅助多端落地
android·ios·小程序·uni‑app·uniapp 四端适配·多端兼容·ai 生成 uni‑app
CocoaKier15 小时前
喜大普奔!2027年春季起,iOS提审最低支持iOS15.0以上
ios·apple
初级代码游戏18 小时前
iOS开发 Swift 速记2:三种集合类型 Array Set Dictionary
开发语言·ios·swift
凡泰AI21 小时前
APP同时覆盖了iOS、安卓和鸿蒙,如何选择混合开发架构才能减少重复建设,提高功能上线效率~
android·ios·harmonyos·mpaas·uni·小程序容器
AIsoft_86881 天前
iPhone录音重点标记:会议录音与重点内容同步保存功能实测
ios·iphone