在Xcode Swift 4中如何复制类实例使其独立于原实例?
解决CClass实例引用共享的问题
这事儿我太熟了!你遇到的问题本质是Swift中类是引用类型导致的——当你把ArrayEntity[i]赋值给ParentOne和ParentTwo时,并没有创建新的CClass实例,只是让这两个变量都指向了数组里同一个实例的内存地址。所以不管你通过哪个变量修改counter,所有指向这个实例的引用都会看到变化,包括数组里的原元素。
要让ParentOne和ParentTwo成为独立的实例,和数组里的元素彻底分开,有几个常用方案:
方案1:给CClass实现自定义拷贝方法
手动写一个方法来复制实例的所有属性,生成新的实例:
class CClass { var counter: Int = 0 // 自定义拷贝方法,复制所有属性 func makeCopy() -> CClass { let newInstance = CClass() newInstance.counter = self.counter // 如果类里还有其他属性,一定要在这里也复制一遍 return newInstance } }
之后赋值的时候调用这个方法:
ParentOne = ArrayEntity[i].makeCopy() ParentTwo = ArrayEntity[i].makeCopy()
方案2:遵循NSCopying协议(适用于Apple平台开发)
如果你的项目是iOS/macOS等Apple平台,可以让类遵循NSCopying协议来实现标准的拷贝逻辑:
import Foundation class CClass: NSObject, NSCopying { var counter: Int = 0 func copy(with zone: NSZone? = nil) -> Any { let copiedInstance = CClass() copiedInstance.counter = self.counter return copiedInstance } }
使用的时候这样赋值:
ParentOne = ArrayEntity[i].copy() as! CClass ParentTwo = ArrayEntity[i].copy() as! CClass
方案3:把类改成结构体(最简单的方案,若适用)
如果你的CClass不需要继承其他类,而且所有属性都是值类型(比如Int、String、自定义结构体等),直接把class改成struct就行——因为结构体是值类型,赋值时会自动创建完整的副本:
struct CClass { // 替换class为struct var counter: Int = 0 }
这样原来的赋值代码完全不用改:
ParentOne = ArrayEntity[i] ParentTwo = ArrayEntity[i]
此时ParentOne、ParentTwo和ArrayEntity[i]都是各自独立的实例,修改任何一个的counter都不会影响其他。
根据你的实际需求选就行啦——如果必须用类就选前两个方案,能改成结构体的话方案3最省心。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

