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

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.lastName newLastName 指向完全不同的地址,对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
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值