iOS copy strong用法

本文详细解释了深拷贝和浅拷贝的概念及其在Objective-C中的应用,通过具体实例展示了不同情况下可变与不可变对象的拷贝行为差异。

copy strong属性用法

定义理解

  • 浅Copy:

    指针的复制,指向同一块内存。

  • 深Copy:

    内存的复制,指向不同的内存,互不干涉。


代码说明

//定义
@property(nonatomic,strong) NSString *s_strong;
@property(nonatomic,copy)   NSString *s_copy;
//定义为可变字符串
NSMutableString *mStr = [NSMutableString stringWithString:@"mStr"];
self.s_strong = mStr;
self.s_copy   = mStr;
NSLog(@"      ms:%@--address:%p",mStr, mStr);
NSLog(@"s_strong:%@--address:%p",_s_strong, _s_strong);
NSLog(@"  s_copy:%@--address:%p",_s_copy, _s_copy);
  • 输出
    • ms: mStr ——address: 0x60000025a3d0
    • s_strong: mStr ——address: 0x60000025a3d0
    • s_copy:mStr ——–address:0xa0000007274536d4 内存地址发生改变
  • 总结:使用可变类型,如:NSMutableString赋值,copy深拷贝,复制了一份内容,并创建了新地址;strong浅拷贝,指向同一个地址。
  • 可变 ==> strong浅拷贝 ;copy深拷贝。
//串追加字符串后
[mStr appendString:@"+add"];

NSLog(@"      ms:%@--address:%p",mStr, mStr);
NSLog(@"s_strong:%@--address:%p",_s_strong, _s_strong);
NSLog(@"  s_copy:%@--address:%p",_s_copy, _s_copy);
  • 输出
    • ms:mStr+add —-address:0x60000025a3d0
    • s_strong:mStr+add —–address:0x60000025a3d0
    • s_copy:mStr —–address:0xa0000007274536d4 //内容不变,地址发生变化
  • 总结:copy深拷贝:指向了不同的地址,内容同样不发生变化; strong浅拷贝:指向了相同的地址。
//定义为不可变字符串
NSString *str = @"str";
self.s_strong = str;
self.s_copy   = str;
NSLog(@"     str:%@--address:%p",str, str);
NSLog(@"s_strong:%@--address:%p",_s_strong, _s_strong);
NSLog(@"  s_copy:%@--address:%p",_s_copy, _s_copy);
  • 输出
    • str:str ——address:0x1047f3548
    • s_strong:str—–address:0x1047f3548
    • s_copy:str——-address:0x1047f3548
  • 总结:定义为不可变 string等属性, copy与strong指向的内容及地址不发生变化;copy,strong均为浅拷贝
  • 不可变 ==> strong==copy 浅拷贝
iOS 开发中,对 `NSArray` 进行深拷贝可以通过多种方式实现,具体取决于数据类型和需求。 ### 使用 `initWithArray:copyItems:` 实现深拷贝 对于包含基本对象(如 `NSString`、`NSNumber` 等)的数组,可以使用 `initWithArray:copyItems:` 方法进行深拷贝。此方法会复制数组中的每一个元素,前提是这些元素本身支持 `NSCopying` 协议。例如: ```objc NSArray *deepCopyArray = [[NSArray alloc] initWithArray:someArray copyItems:YES]; ``` 这种方式适用于集合对象本身以及其内部元素都需要独立副本的场景[^1]。 ### 使用归档与解档实现深拷贝 如果数组中包含自定义对象或需要更彻底的深拷贝,可以通过归档(`NSKeyedArchiver`)和解档(`NSKeyedUnarchiver`)的方式实现深拷贝。前提是自定义类需要遵循 `NSCoding` 协议,并正确实现编码和解码方法。例如: ```objc NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:oldArray]; NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData]; ``` 此方法能够确保数组及其所有元素都独立存在于内存中,适用于复杂的对象结构[^2]。 ### 自定义类的深拷贝实现 对于自定义类的对象,如 `Person` 类,如果希望其支持深拷贝,需要实现 `NSCopying` 或 `NSMutableCopying` 协议,并在 `copyWithZone:` 方法中手动复制每个属性。例如: ```objc @interface Person : NSObject <NSCopying> @property (nonatomic, strong) NSString *name; @property (nonatomic, assign) NSInteger age; @end @implementation Person - (id)copyWithZone:(NSZone *)zone { Person *copy = [[Person allocWithZone:zone] init]; copy.name = self.name; copy.age = self.age; return copy; } @end ``` 只有实现了 `copyWithZone:` 方法,`initWithArray:copyItems:` 和 `copy` 操作才能正确执行深拷贝[^4]。 ### 注意事项 - 如果数组元素本身不支持 `NSCopying` 协议,调用 `copyItems:YES` 会导致运行时错误。 - 在使用归档方式进行深拷贝时,必须确保数组中的所有对象都实现了 `NSCoding` 协议。 - 对于不可变数组的拷贝,使用 `copy` 通常只是浅拷贝;若需要深拷贝,必须显式调用上述方法之一。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值