第一种情况: 使用 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.m
int 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 = 0x100001078
newLastName = newname, newLastName address = 0x1003031e0
lastname = newname, lastname address = 0x100303720
从以上打印的结果可以看到,第一次打印的 lastname address和第二次打印的 lastname address 结果并不相同,同时 newLastName address 和第二次打印的 lastname address 也不相同,说明执行 p1.lastName = newLastName 之后 p1.lastName 指向了一块全新的内存空间。
在这里,由于 copy 的作用,在赋值的过程中,newLastName 产生了一个不可变的副本,而 p1.lastName 则指向此副本。所以对 newLastName 做一些操作的时候是不会影响到 p1.lastName 的。
改变一: 修改 main 方法中的代码
NSString *newLastName = @"newname";
在执行 p1.lastName = newLastName 语句之后,两者指向同一个地址,仅仅是简单的赋值操作。
第二种情况: 使用 strong 修饰
将代码:
@property (nonatomic, copy) NSString *lastName;
修改为:
@property (nonatomic, strong) NSString *lastName;
执行代码片段1之后的结果如下:
lastname = name, lastname address = 0x100001068
newLastName = newname, newLastName address = 0x100202e00
lastname = 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 = 0x100202e00
lastname = newnameabc, lastname address = 0x100202e00
因为 newLastName 和 p1.lastname 指向同一个内存,对 newLastName 的改变也就改变了 p1.lastname。但是 lastname 属性是不可变的 NSString 类型,而在这里却发生了改变。
结论
用 copy 修饰的 NSString 如果在无意中被一个 NSMutableString 类型的变量赋值,该 NSMutableString 类型的变量会被 copy 出一个不可变副本,将该副本赋值给 NSString 类型的变量,万一 NSMutableString 的值被修改,不会影响到 NSString 的值。
用 strong 修饰的 NSString 如果在无意中被一个 NSMutableString 类型的变量赋值,则直接将指针指向该 NSMutableString 类型的变量,一旦 NSMutableString 的值被修改,NSString 的值也就发生了改变,这与 NSString 作为不可变类型相违背。
当然如果 NSString 被一个 NSString 赋值,copy 的效果与 strong 的效果是一样的,直接改了就是。







网友评论