iOS中字符串类及copy协议

一、字符串的修饰符

iOS中对象的字符串类型的属性一般声明为:

@property (nonatomic, copy) NSString *name;  // copy

测试

NSMutableString *name = [NSMutableString stringWithFormat:@"QQQ"];
    
StringClass *sc = [StringClass new];
sc.name = name;
    
NSLog(@"name:%p, sc.name:%p", name, sc.name);
    
NSLog(@"name:%@, sc.name:%@", name, sc.name);
[name appendString:@"WWW"];
NSLog(@"name:%@, sc.name:%@", name, sc.name);

理想的打印结果

name:0x1004039f0, sc.name:0x51515135 //内容的拷贝
name:QQQ, sc.name:QQQ
name:QQQWWW, sc.name:QQQ

如果用strong修饰变成强指针,打印结果

name:0x100302f30, sc.name:0x100302f30 //指针的拷贝
name:QQQ, sc.name:QQQ
name:QQQWWW, sc.name:QQQWWW
//sc.name的值被修改了。

总结:如果一个对象的NSString属性被NSString类型的变量赋值,copy和strong无所谓(不可变字符串是常量!),如果NSString属性被NSMutableString类型变量赋值必须用copy修饰。否则NSString属性的值很容易被非法改变。
当然,如果重写NSString属性的的set方法,并做安全措施也行。

二、不可变字符串是常量
NSString *string = [NSString stringWithFormat:@"string"];
    
NSString *newString = string;
    
NSString *newNewString = [string copy]; // 一种安全措施
    
NSString *string1 = [NSString stringWithFormat:@"string"];
    
NSLog(@"\nstring:%p, \nString:%p, \nString:%p, \nString:%p", string, newString, newNewString, string1);

打印结果:指向同一个地址。常量区。

2017-03-01 20:52:11.792176 StringPoint[32162:326630]
string:0x676e6972747365,
String:0x676e6972747365,
String:0x676e6972747365,

String:0x676e6972747365

总结:真正的NSString类型字符串都是常量。并且如果字符串的内容内存中已经有过(常量池),会指向字符串出现的那块旧内存,并不会开辟新的内存,从而达到节省能存空间的效果。

三、NSString、NSMutableString的copy协议

类中有NSString类型的属性name,用copy修饰。在其set方法(⭐️)里,
如果入参为NSString类型的变量,则是name指向字符串的地址;
如果入参为NSMutableString类型的变量,则name指向一块新的内存,新内存上变量是一样的NSString类型的字符串,数据更安全。

NSString、NSMutableString对应的copy、mutableCopy方法情况

copy mutableCopy
NSString 返回入参字符串 返回可变的新字符串
NSMutableString 返回不可变的新字符串 也是返回可变的新字符串

注意常量池。

四、copy协议

对于一个类,可以自定义copy和mutableCopy方法。

你可能感兴趣的:(iOS中字符串类及copy协议)