iOS中NSString 使用 copy 和 strong 修饰的区别详解

来源:互联网 发布:血源诅咒小丑捏脸数据 编辑:程序博客网 时间:2024/05/17 09:35

ios开发中,NSString使用 copy 与strong 修饰有什么区别呢?接下来小编就和大家一起来扒一扒。

第一种情况: 使用 copy 修饰

// 代码片段1// Person.h

@interface Person : NSObject

@property (nonatomic, copy) NSString *lastName;

@end

// Person.m

@implementation Person

- (instancetype)init {

self = [super init];

if (self) {

_lastName = @"name";

}

return self;

}

@end

// main.mint main(int argc, const char * argv[]) {

Person *p1 = [[Person alloc] init];

NSLog(@"lastname = %@, lastname address = %p", p1.lastName, p1.lastName);

NSMutableString *newLastName = [[NSMutableString alloc] initWithString:@"newname"];

NSLog(@"newLastName = %@, newLastName address = %p", newLastName, newLastName);

p1.lastName = newLastName;

NSLog(@"lastname = %@, lastname address = %p", p1.lastName, p1.lastName);

return 0;

}

  以上代码执行后的结果如下:


lastname = name, lastname address = 0x100001078newLastName = newname, newLastName address = 0x1003031e0lastname = newname, lastname address = 0x100303720

  从以上打印的结果可以看到,第一次打印的 lastname address 和第二次打印的 lastname address 结果并不相同,同时newLastName address 和第二次打印的lastname address 也不相同,说明执行p1.lastName = newLastName 之后p1.lastName 指向了一块全新的内存空间,这就是copy 的作用:重新开辟一块内存空间存放newLastName 的值。

  改变一: 修改 main方法中的代码,在 return 0之前添加以下代码

[newLastName appendString:@"abc"];

NSLog(@"lastname = %@, lastname address = %p", p1.lastName, p1.lastName);

newLastName 的值变成了 newnameabc,但是 p1.lastName的值没有任何变化。这很简单,根据 copy的作用 p1.lastNamenewLastName指向完全不同的地址,对newLastName做的改变自然不会反映在 p1.lastName上。

第二种情况: 使用 strong 修饰

  将代码:

@property (nonatomic, copy) NSString *lastName;

  修改为:

@property (nonatomic, strong) NSString *lastName;

  执行代码片段1之后的结果如下:

lastname = name, lastname address = 0x100001068newLastName = newname, newLastName address = 0x100202e00lastname = newname, lastname address = 0x100202e00

  从以上结果中发现第一次打印的 lastname address 和第二次打印的 lastname address 指向不同的内存,但是第二次打印的lastname address newLastName address 相同,说明,与copy 不同的是,strong 并没有开辟一块新的内存空间,而是直接将lastname 指向了newLastName

  改变一: 修改 main方法中的代码,在 return 0之前添加以下代码

[newLastName appendString:@"abc"];

NSLog(@"newLastName = %@, newLastName address = %p", newLastName, newLastName);

NSLog(@"lastname = %@, lastname address = %p", p1.lastName, p1.lastName);

  打印结果如下:

newLastName = newnameabc, newLastName address = 0x100202e00lastname = newnameabc, lastname address = 0x100202e00

  因为 newLastName p1.lastname 指向同一个内存,对newLastName 的改变也就改变了p1.lastname 。但是lastname 属性是不可变的NSString 类型,而在这里却发生了改变。

另外

  如果有以下代码:

@property (nonatomic, copy) NSMutableString *mString;

  如果在未来给 mString 重新赋了一个新值,则会产生一个不可变的副本,此时想在mString 上调用 NSMutableString的相关方法是不行的。

结论

  用 copy 修饰的 NSString 如果在无意中被一个NSMutableString 类型的变量赋值,原先的NSString 会被copy 一份用来存储NSMutableString 的值,万一NSMutableString 的值被修改,不会影响到NSString 的值,这能体现NSString 作为不可变类型的性质。

  用 strong 修饰的NSString 如果在无意中被一个NSMutableString 类型的变量赋值,NSString 不会被拷贝,一旦NSMutableString 的值被修改,NSString 的值也就发生了改变,这与NSString 作为不可变类型相违背。

  当然如果 NSString 被一个 NSString 赋值,copy 的效果与strong 的效果是一样的,直接改了就是。

  以上的结论同样适用于 NSArray NSDictionary

 

文章来源:简书


0 0
原创粉丝点击