版权声明:本文为博主原创文章,未经博主允许不得转载。 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的整数有效