美文网首页
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指针优化

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