剖析 Objective-C 类的 copy 操作:深拷贝与浅拷贝对对象属性的影响
·
Objective-C 类的 Copy 操作:深拷贝与浅拷贝对对象属性的影响
在 Objective-C 中,拷贝操作通过 NSCopying 和 NSMutableCopying 协议实现,其核心区别在于对象属性的复制深度:
1. 浅拷贝 (Shallow Copy)
- 定义:仅复制对象本身,不复制其内部属性对象
- 属性影响:
- 新对象与原对象共享所有属性对象的引用
- 修改新对象的属性会影响原对象
- 适用于不可变属性(如
NSString)
- 实现示例:
- (id)copyWithZone:(NSZone *)zone {
MyClass *copy = [[[self class] alloc] init];
copy.propertyA = self.propertyA; // 直接指针赋值
copy.propertyB = self.propertyB; // 共享引用
return copy;
}
2. 深拷贝 (Deep Copy)
- 定义:递归复制对象及其所有属性对象
- 属性影响:
- 新对象拥有完全独立的属性副本
- 修改新对象属性不影响原对象
- 必需用于可变属性(如
NSMutableArray)
- 实现示例:
- (id)copyWithZone:(NSZone *)zone {
MyClass *copy = [[[self class] alloc] init];
copy.propertyA = [self.propertyA copy]; // 浅拷贝不可变对象
copy.propertyB = [[NSMutableArray alloc] initWithArray:self.propertyB copyItems:YES]; // 深拷贝
return copy;
}
3. 关键影响因素分析
| 属性类型 | 浅拷贝效果 | 深拷贝效果 |
|---|---|---|
NSString |
✅ 安全(不可变) | ⚠️ 冗余复制 |
NSMutableString |
❌ 危险(共享可变状态) | ✅ 必需 |
NSArray |
✅ 安全(元素未复制) | ⚠️ 元素仍共享 |
NSMutableArray |
❌ 元素共享 | ✅ 元素独立 |
| 自定义对象 | ❌ 共享引用 | ✅ 递归复制 |
4. 实现规范建议
-
不可变对象:
@property (copy) NSString *title; // 自动浅拷贝- 系统自动调用
[value copy] - 对
NSString实际是引用计数增加
- 系统自动调用
-
可变对象:
NSMutableArray *deepCopy = [[NSMutableArray alloc] initWithArray:originalArray copyItems:YES];- 需递归实现
NSCopying - 使用
copyItems:YES触发元素拷贝
- 需递归实现
-
自定义对象:
- (id)copyWithZone:(NSZone *)zone { MyClass *copy = [[[self class] alloc] init]; copy.subObject = [self.subObject copy]; // 委托拷贝 return copy; }
5. 内存模型对比
浅拷贝:
[对象A] --→ [属性X]
[对象B] --↗
深拷贝:
[对象A] --→ [属性X]
[对象B] --→ [属性X_copy]
最佳实践
-
声明
@property时:- 不可变对象用
copy - 可变对象用
strong+ 手动深拷贝
- 不可变对象用
-
实现
copyWithZone:时:- 基础类型直接赋值
- 对象属性调用
copy或mutableCopy - 集合类型使用
initWithArray:copyItems:YES
-
避免:
copy.property = [mutableObj retain]; // ❌ 错误:仍是浅拷贝
通过合理选择拷贝策略,可有效避免由对象共享导致的不可预测行为,确保数据状态的隔离性和线程安全。
更多推荐


所有评论(0)