关于字符串的类型以及深拷贝探索

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ldszw/article/details/82926701

关于字符串的类型以及深拷贝

首先看如下代码:

@interface ViewController ()
@property (nonatomic, copy) NSString *aString;
@property (nonatomic, copy) NSMutableString *bString;
@property (nonatomic, strong) NSString *cString;
@property (nonatomic, strong) NSMutableString *dString;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSString *testString = @"test";
    
    self.aString = [testString mutableCopy];
    self.bString = [testString mutableCopy];
    self.cString = [testString mutableCopy]; 
    self.dString = [testString mutableCopy];
    NSLog(@"origin:地址-%p, class-%@", testString, [testString class]);
    NSLog(@"a:地址-%p, class-%@", self.aString, [self.aString class]);
    NSLog(@"b:地址-%p, class-%@", self.bString, [self.bString class]);
    NSLog(@"c:地址-%p, class-%@", self.cString, [self.cString class]);
    NSLog(@"d:地址-%p, class-%@", self.dString, [self.dString class]);
}

打印结果如下:

2018-06-13 18:22:27.731094+0800 Test[4771:1665524] origin:地址-0x100c24228, class-__NSCFConstantString
2018-06-13 18:22:27.731156+0800 Test[4771:1665524] a:地址-0xa000000747365744, class-NSTaggedPointerString
2018-06-13 18:22:27.731170+0800 Test[4771:1665524] b:地址-0xa000000747365744, class-NSTaggedPointerString
2018-06-13 18:22:27.731208+0800 Test[4771:1665524] c:地址-0x1c4252270, class-__NSCFString
2018-06-13 18:22:27.731251+0800 Test[4771:1665524] d:地址-0x1c42520f0, class-__NSCFString

按理来说,深拷贝后的地址应该是不一样的。但是很明显带有copy属性的字符串地址却是一样的。而且testString的类型为NSCFConstantString,copy属性的字符串类型为NSTaggedPointerString,strong属性的字符串类型为NSCFString。

那么究竟是什么原因产生了这个差异,而这个NSTaggedPointerString又是什么?接下改变因素试一试,我们将属性全部改成strong或者copy,改变testString的类型为不可变或者可变,改变testString调用copy或者mutableCopy(只改变其中之一)。

结果:只要最后调用了copy操作的字符串,地址都是一样的,而且类型全部为NSTaggedPointerString。

而且数字的长度大于9,英文字母的长度大于11,或者是中文则不都不为NSTaggedPointerString,是按照原来设想的所打印。

那么NSTaggedPointerString是什么呢?Tagged Pointer是苹果一个能提高性能,节省内存的技术,而且对NSNumber和NSString有效。Tagged Pointer是一个伪指针,直接指向内存地址所对应的数值,可以省下一次真正对象的内存分配和间接取值的时间。但是只对内存小于60位的字符串和小于2^60-1的整数有效

猜你喜欢

转载自blog.csdn.net/ldszw/article/details/82926701