iOS Strong和Copy 理解

在iOS开发中,为防止赋值给属性的是可变数据,如NSString或NSArray,通常选择使用copy属性修饰。当源字符串是NSMutableString时,strong只会增加引用计数,而copy会执行深拷贝,生成新对象。尽管深拷贝可能导致内存浪费,但为了确保不可变对象的不变性,通常推荐使用copy。此外,文章还详细解释了内存管理的关键字,如Strong、Weak、Assign、Copy以及Atomic和Nonatomic的区别。

问题描述

在定义一个类的property时候,为property选择strong还是copy特别注意和研究明白的,如果property是NSString或者NSArray及其子类的时候,最好选择使用copy属性修饰。为什么呢?这是为了防止赋值给它的是可变的数据,如果可变的数据发生了变化,那么该property也会发生变化。

代码示例 

首先声明了两个NSString属性,如下:

@property(nonatomic, strong) NSString *strongStr;
@property(nonatomic, copy) NSString *copyyStr;

下面我们分别以NSString和NSMutableString举例

NSString场景一

NSString 场景一

结论:这种情况下,不管是用strong还是copy修饰的对象,其指向的地址都是originStr的地址。

NSString场景二   

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` 通常只是浅拷贝;若需要深拷贝,必须显式调用上述方法之一。 ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值