OC-copy与strong区别(深拷贝 浅拷贝)

167 阅读2分钟

对于可变对象 (NSMutableStringNSMutableDictionaryNSMutableArray) 与 不可变对象 (NSStringNSDictionaryNSArray)而言,在@property中存在copystrong修饰符,不存在mutableCopy

修饰不可变的对象属性一般用copy深拷贝,修饰可变的对象属性一般用strong浅拷贝 先看一下代码:

#import "ViewController.h"

@interface ViewController ()
@property(nonatomic, strong) NSMutableString *strMutStrong;
@property(nonatomic, copy) NSMutableString *strMutCopy;
@property(nonatomic, copy) NSString *strCopy;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSMutableString *strM = [NSMutableString stringWithString:@"strM"];
    self.strCopy = strM;
    self.strMutStrong = strM;
    self.strMutCopy = strM;
    
    [strM appendString:@"str"];
    
    NSLog(@"%@---%p", strM, strM); // 内容:strMstr  加入地址是:0x010
    NSLog(@"strCopy:%@---%p", self.strCopy, self.strCopy); // strM  0x011
    NSLog(@"strMutStrong:%@---%p", self.strMutStrong, self.strMutStrong); // strMstr  0x010
    NSLog(@"strMutCopy:%@---%p", self.strMutCopy, self.strMutCopy); // strM 0x011    
}

打印结果截图: 打印结果.png 解释如下: 1、对于NSStringCopy修饰的时候,其实就是在setter方法内部默认实现了copy方法,从可变到不可变进行copy属于深拷贝,指针和内存全部复制一份,内容不变,内存地址发生变化。之前的strM变量内容被改变时也不会影响到strCopy的内容,比较安全。

2、对于NSMutableStringstrong修饰时候,只是多了一个指针指向原本的对象,内容与地址始终保持是一直的。

3、对于NSMutableStringcopy修饰的时候,strMutCopysetter方法内部也会有copy方法调用,strMutCopy已经是一个不可变的对象属性,与strCopy相同地址与内容

分别打印class如下所示: class.png 由截图可知: strMself.strMutStrong__NSCFString可变 self.strCopyself.strMutCopyNSTaggedPointerString不可变,如果调用appendString:程序会crash

再次举例:

总结说明:property使用stongcopy分析 浅拷贝深拷贝!!!! @property strong 指针拷贝(互相影响) copy内容拷贝(人与人的关系,互不影响)


@property (nonatomic, strong) NSString *myObject; // 指针拷贝
@property (nonatomic, strong) NSMutableString *myObjectMut; // 指针拷贝  唯一区别 myObjectMut可以修改  myObject不可以
@property (nonatomic, copy) NSString *myObjectCopy; // 内容拷贝


// property使用stong和copy分析 浅拷贝深拷贝!!!!
// @property strong 指针拷贝(互相影响) copy内容拷贝(人与人的关系,互不影响)
- (void)propertyStrongAndCopy{
    
    NSMutableString *str = [NSMutableString stringWithString:@"12345"];
    self.myObject = str; // 12345
    self.myObjectMut = str; // 12345
    self.myObjectCopy = str; // 12345
    
    [str replaceCharactersInRange:NSMakeRange(1, 2) withString:@"A"];
    
    NSLog(@"str: %@", str); // 1A45
    NSLog(@"self.myObject: %@", self.myObject); // 1A45
    NSLog(@"self.myObjectMut: %@", self.myObjectMut); // 1A45
    NSLog(@"self.myObjectCopy: %@", self.myObjectCopy); // 12345
    
    // 修改copy后的数据
    self.myObject = @"myobject"; // 重新指向
    self.myObjectMut = [NSMutableString stringWithString:@"myObjectMut"]; // 重新指向 相当于创建了新对象!
    [self.myObjectMut replaceCharactersInRange:NSMakeRange(1, 2) withString:@"B"]; // mBbjectMut 修改旧对象!
//    [self.myObject replaceCharactersInRange:NSMakeRange(1, 2) withString:@"B"]; // error
    
    NSLog(@"str: %@", str);// 1A45
    NSLog(@"self.myObject: %@", self.myObject); // myObject
    NSLog(@"self.myObjectMut: %@", self.myObjectMut); // myObjectMut
    NSLog(@"self.myObjectCopy: %@", self.myObjectCopy); // 12345 内容拷贝!!!
}

参考__NSCFString \NSTaggedPointerString部分解析 深拷贝浅拷贝