美文网首页
objective-c对象缓存与tagged指针优化

objective-c对象缓存与tagged指针优化

作者: macroC | 来源:发表于2019-03-15 11:50 被阅读0次

背景

工程中出现了一段看似必崩的代码,比较好奇,代码如下:

– (void)setSomeThing:(BOOL)someThing {
objc_setAssociatedObject(self, kIsPreviewKey, [NSNumber numberWithBool:someThing], OBJC_ASSOCIATION_ASSIGN);
}

– (BOOL)isPreview {
id temp = objc_getAssociatedObject(self, kIsPreviewKey);
return [temp boolValue];
}

上述在一个类中,动态添加了一个 BOOL 类型的属性。以上是属性的 setter+getter 方法,已知以 OBJC_ASSOCIATION_ASSIGN 为参数是无法存储对象类型变量的,setter方法中 [NSNumber numberWithBool:someThing] 返回的变量并没有增加引用计数,离开 setter 方法后将在当前 runloop 末尾收到 release 消息后被置 nil,推知 getter 方法中 temp 指针实际指向的空间已经释放,于是 一个野指针异常条件满足。

然而,实际上这段代码非但不会崩溃,并且也实现了编写者预期的功能,能正确的存取动态添加的属性,结果令人吃鲸。

对象缓存机制

另一番测试:以 BOOL 类型变量初始化 NSNumber 对象,以 10 以下的整型变量初始化 NSNumber 对象。用例例如(在32位机器上运行):

– (void)viewDidLoad{
    [super viewDidLoad];
    NSNumber *numTempInt = [NSNumber numberWithInt:3];
    NSNumber *numTempBool = [NSNumber numberWithBool:YES];
    NSLog(@”temp_int_p_2%p”,numTempInt);
    NSLog(@”temp_bool_p_2%p”,numTempBool);
    [self testFunc];
}

– (void)testFunc{
    NSNumber *numTempInt = [NSNumber numberWithInt:3];
    NSNumber *numTempBool = [NSNumber numberWithBool:YES];
    NSLog(@”temp_int_p_1=%p”,numTempInt);
    NSLog(@”temp_bool_p_1%p”,numTempBool);
}

得到的结果 temp_int_p_1 与 temp_int_p_2 相同,temp_bool_p_1 与 temp_bool_p_2 相同。然而尝试100以上的较大数字,结果不再神奇,对应的值不在相同。

因为系统对 NSNumber 对象的缓存,部分常用的较小的值,初始化以后常驻内存,新初始化相同的值不再重新分配内存并初始化。

tagged 指针优化

简介如下:在 64 位 IOS 机器上,苹果为优化内存占用,优化运行速度等考虑,提出并实现了 tagged 指针机制。

tagged 指针特征表现如下:使用 numberWithXXX : argu 初始化对象时,若参数数据实际占用的空间小于64-8-1=55位, 即以整型数据为例,去掉一位符号位,最大值占 54 位,即 2^55-1,这样得到的 NSNumber 对象并不是真正的 OC 对象,其指针也并没有指向 OC 对象,输出指针地址易见指针中除去末位和首字节以外,其余各位组成的数字等于 argu 的值。

经测试,末位字节用来表示 argu 参数的类型。

使用上文中对象缓存机制的实例代码后,得到的结果和对象缓存实验结果相同,但temp_int_p_1与temp_int_p_2,以及 temp_bool_p_1与temp_bool_p_2 有更明显的特征(tagged 指针特征)。

对于较小的类型如 NSNumber NSDate 等,在64位机器上,使用 tagged 指针优化还是很常见的;而在 32 位机器上,对象缓存机制也做到了对小型对象的初始化和访问优化。

相关文章

  • objective-c对象缓存与tagged指针优化

    背景 工程中出现了一段看似必崩的代码,比较好奇,代码如下: 上述在一个类中,动态添加了一个 BOOL 类型的属性。...

  • (转)谈weak对象、对象缓存以及Tagged Pointer

    1.weak对象什么时候释放 2.系统对象的缓存 3.Tagged Pointer对象 __weak NSArra...

  • iOS程序的内存布局

    iOS引入Tagged Pointer技术,为了优化NSString、NSNumber、NSDate小对象的存储。...

  • 内存管理 Tagged Pointer

    Tagged Pointer通常创建对象,对象存储在堆中,对象的指针存储在栈中。我们要找到这个对象,就需要先在栈中...

  • iOS 内存管理-Tagged Pointer

    Tagged Pointer 从64位系统开始,iOS引入了TaggedPointer技术,用于优化小对象(NSN...

  • Swift----声明

    在Objective-C中,通过使用指针来处理对象引用,指针可以为空,在Objective-C中称为nil。在Sw...

  • NSTaggedPoint

    0x01 TaggedPoint由来 从64位开始,iOS引入了Tagged Pointer技术,用于优化小对象...

  • id 和void *

    1. 指针类型 id是指向Objective-C对象的指针。 void *是任何东西的指针(无类型指针)。是“对...

  • OC对象的本质(下)

    iOS | OC对象本质 | Objective-C OC对象的分类,对象的isa指针指向哪里,superClas...

  • iOS进阶-底层探索

    Objective-C对象模型 isa指针 Objective-C是一门面向对象的编程语言,每一个对象都是一个实例...

网友评论

      本文标题:objective-c对象缓存与tagged指针优化

      本文链接:https://www.haomeiwen.com/subject/eqjlmqtx.html