NSArray和NSString copy属性问题

什么时候加copy

在定义属性的时候,如果属性的数据类型有对应的Mutable类型,那么该非Mutable类型属性要指定为为copy。比如:NSString/NSMutableString、NSArray/NSMutableArray、NSDictionary/NSMutableDictionary、NSSet/NSMutableSet。如下图:

NSArray和NSString copy属性问题

测试例子

下面示例说明:

  • 在mutable类型再给对应非mutable类型赋值的时候,对应有mutable的类型一般都需要在属性里面指定copy,否则非mutable类型的数据是不稳定的。

  • 非mutable类型指定为copy后,copy的只是MutableArray的数组索引,里面的数据元素依然和MutableArray中的对象元素地址是一样的。

  • 下面例子对NSArray做实验,也适用于NSString。

 

@interface QRATestViewController ()
 
@property (nonatomic, copy) NSArray *testCopyArray;
@property (nonatomic, strong) NSArray *testStrongArray;
// 带mutable的类型定义属性不能加copy
@property (nonatomic, copy) NSMutableArray *testMutableArray;
 
@end
 
- (IBAction)testTouchUp:(id)sender {
    // 在这里可以做一些简单的测试工作
    NSMutableArray *mutableArray = [[NSMutableArray alloc] init];
    [mutableArray addObject:@"111"];
     
    self.testCopyArray = mutableArray;
    self.testStrongArray = mutableArray;
     
    [mutableArray addObject:@"2222"];
     
    // testCopyArray中的元素不包含2222,但是testStrongArray中的数组元素中包含2222
    // 表示mutableArray数组元素的变化不会影响到testCopyArray
    NSLog(@"%@  %@", self.testCopyArray, self.testStrongArray);
     
    // 输出的对象地址是一样的,表示testCopyArray中的元素依然是原先对象
    NSLog(@"%p  %p", self.testCopyArray[0], mutableArray[0]);
     
    // 因为testMutableArray带了copy,所以这里默认是copy不是mutableCopy,导致下面一行crash
    self.testMutableArray = mutableArray;
    [self.testMutableArray addObject:@"333"];
     
    NSLog(@"%@", self.testMutableArray);
}

参考链接