美文网首页
NSTaggedPointer

NSTaggedPointer

作者: 三国韩信 | 来源:发表于2020-07-19 23:47 被阅读0次

TaggedPointer是苹果引入的对内存管理进一步优化的一种策略。下面以NSString为例,说明它。showCode:

一、用@"" 这种初始化的字符串
    NSString *string = @"123456";
    NSLog(@"%@,%p,%@",string,self.string,[string class]);

    打印结果:123456,  0x1076e9198,  __NSCFConstantString

可以看出,这种情况下的string是一个__NSCFConstantString类型,看它的内存地址,比不是放在栈区,也不是堆区,是放在常量区的。可见__NSCFConstantString代表的是一个字符串常量。
注: 这种写法也是一样的,[[NSString alloc] initWithString:@"222"];

二、用stringWithFormat初始化的字符串
NSString *  s1 = [NSString stringWithFormat:@"123456789"];
NSLog(@"%@,%p,%@",s1,s1,[s1 class]);

NSString *  s2 = [NSString stringWithFormat:@"1234567890"];
NSLog(@"%@,%p,%@",s2,s2,[s2 class]);

NSString *  s3 = [[NSString alloc] initWithFormat:@"123456789"];
NSLog(@"%@,%p,%@",s3,s3,[s3 class]);

NSString *  s4 = [[NSString alloc] initWithFormat:@"1234567890"];
NSLog(@"%@,%p,%@",s4,s4,[s4 class]);

打印结果:
123456789,     0xdb939874c869cf6b,   NSTaggedPointerString
1234567890,    0x600003bbb600,       __NSCFString
123456789,     0xdb939874c869cf6b,   NSTaggedPointerString
1234567890,    0x600003bd1000,       __NSCFString

这里,就出现了NSTaggedPointerString。那么何为NSTaggedPointerString呢?
是苹果对于一些小变量(小的数据,短的字符串)的一种表示的方式。(NSString、NSNumber)
NSTaggedPointer类型的数据,它的表现形式为:地址+值。它的数据本身就存储在地址里,它不用另外的去开辟堆栈空间之类的,所以他也不适用于苹果对普通对象的那套retain/release模式。


TaggedPointer

那么多小的变量算是苹果所谓的小数据呢,网上传说的是字符串只要少于9个就是,所以上面的例子中分别用了9个和10个字符来实验。而且,多次初始化相同的NSTaggedPointerString,它的地址是不变的。

正因为NSTaggedPointerString不存在retain和release的操作,所以面试中也经常被坑。如下题:

- (void)taggedPointerDemo {
  
    self.queue = dispatch_queue_create("com.taggedPointer.cn", DISPATCH_QUEUE_CONCURRENT);
    
    for (int i = 0; i<10000; i++) {
        dispatch_async(self.queue, ^{
            self.nameStr = [NSString stringWithFormat:@"cooci"];
             NSLog(@"%@",self.nameStr);
        });
    }
}

-(void)nomalStringDemo {
    self.queue = dispatch_queue_create("com.nomalString.cn", DISPATCH_QUEUE_CONCURRENT);
     NSLog(@"来了");
    for (int i = 0; i<10000; i++) {
        dispatch_async(self.queue, ^{
            self.nameStr = [NSString stringWithFormat:@"和谐学习,不急不躁,才能进步"];
            NSLog(@"%@",self.nameStr);
        });
    }
}

以上2个方法运行,哪个会奔溃?
解析:上面都是多线程异步去调用的,nomalStringDemo这个方法会奔溃。原因是这个方法里多线程去对self.nameStr赋值,
相当于调用了它的setter方法,它的setter方法里面有retain/release的操作,而这里又没有加锁,
多线程去调用release的话,会出现对同一个对象多次release的情况,所以会奔溃。
而第一方法不会奔溃,正是因为它的string是NSTaggedPointerString,它本身并不会去retain/release(或者说它的retain/release啥都没做),
而且他的地址都是一样的,所以不会奔溃。

相关文章

  • NSTaggedPointer

    TaggedPointer是苹果引入的对内存管理进一步优化的一种策略。下面以NSString为例,说明它。show...

  • NSTaggedPointer

    看如下代码,在调试的过程中,出现了_NSCFConstantString,_NSTaggedPointerStri...

  • iOS-内存管理

    前言 说到iOS的内存管理,大致应该分为以下几个方面: NSTaggedPointer 类型 alloc,reta...

  • 伪指针 NSTaggedPointer

    举例0xa000000007070703 这个指针是最初没有想到的 环境 这是时候报错NSTaggedPointe...

  • NSTaggedPointer和NONPOINTER_ISA

    内存管理之Tagged pointer iOS开发者对引用计数这个名词肯定不陌生,引用计数是苹果为了方便开发者管理...

网友评论

      本文标题:NSTaggedPointer

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