我在谈论ARC项目。
我总是声明像这样的数组属性
@property (strong, nonatomic) NSArray *myArray;
但我看到很多人建议使用它:
@property (copy, nonatomic) NSArray *myArray;
人们建议复制说" myArray上的副本是为了防止另一个"所有者"您设置的对象。"这个"解释"克林顿对我说话。
有人可以在我5岁时解释这个含义吗?好的,把它变成3。
感谢
答案 0 :(得分:13)
复制很浅,它只复制指针。如果数组包含可变对象并且该对象已更改,则更改将显示在复制的数组中。
NSMutableString *s = [@"test1" mutableCopy];
NSArray *a1 = @[s];
NSArray *a2 = [a1 copy];
NSLog(@"\na1: %1$p, %1$@\na2: %2$p, %2$@", a1, a2);
[s appendString:@"2"];
NSLog(@"\na1: %1$p, %1$@\na2: %2$p, %2$@", a1, a2);
输出:
a1: 0x10010fed0, (
test1
)
a2: 0x10010fed0, (
test1
)
a1: 0x10010fed0, (
test12
)
a2: 0x10010fed0, (
test12
)
复制的原因是为了在被复制的数组是可变数组的情况下进行保护,以便原始数组的任何更改都不会更改复制的数组。不同之处在于可变数组的变化和可变数组中对象的变化。注意,进一步的原因是人们可能不知道被分配的数组是否可变。
NSString *s1 = @"test1";
NSString *s2 = @"test2";
NSMutableArray *a1 = [@[s1] mutableCopy];
NSArray *a2 = [a1 copy];
NSLog(@"\na1: %1$p, %1$@\na2: %2$p, %2$@", a1, a2);
[a1 addObject:s2];
NSLog(@"\na1: %1$p, %1$@\na2: %2$p, %2$@", a1, a2);
输出:
a1: 0x100200510, (
test1
)
a2: 0x100200650, (
test1
)
a1: 0x100200510, (
test1,
test2
)
a2: 0x100200650, (
test1
)
请注意,不可变NSArray上的副本只执行赋值,因此不需要任何成本。当分配的数组是NSMutableArray时,只有一个副本。
NSString *s1 = @"test1";
NSString *s2 = @"test2";
NSArray *a1 = @[s1];
NSArray *a2 = [a1 copy];
NSLog(@"\na1: %1$p, %1$@\na2: %2$p, %2$@", a1, a2);
输出:
a1: 0x100300140, (
test1
)
a2: 0x100300140, (
test1
)
答案 1 :(得分:2)
问题是,在设置属性后,数组可能会发生变异,即使该属性被定义为不可变数组。例如,考虑一下,
NSMutableArray *array = [NSMutableArray arrayWithObjects:@1, @2, @3, nil];
obj.myArray = array;
[array addObject:@4];
如果将myArray
定义为strong
,则通过更改本地可变数组也会更改myArray
的{{1}}属性。
通过将obj
定义为myArray
,可确保您不必担心数组本身会发生变异。
您仍然需要担心数组中的对象发生变化,如果这也是一个问题,您可能会考虑进行深层复制。
答案 2 :(得分:1)
很简单,请在视图控制器的某处考虑
NSArray *myArrayCopy = self.myArray
现在如果myArray很强,那么如果你更改myArrayCopy中的某个对象,myArray会自动更改。而在复制的情况下,它不会改变,因为它会将myArray的副本分配给myArrayCopy。
答案 3 :(得分:1)
这取决于您是否要处理相同的数据。 copy确实也是“强”的,因此在强指针设置为nil之前,对象不会被销毁。 但是,强大的引用同一个对象,而副本引用对象的副本。生成的setter类似于:
-(void)setStrongArray:(NSArray*)data
{
_strongArray = data;
}
-(void)setCopyArray:(NSArray*)data
{
_strongArray = [data copy];
}