第一种情况: 使用 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
的效果是一样的,直接改了就是。
网友评论