iOS swift中所有对象的引用相同
在swift 4.2中,我在处理两个数组对象时遇到了这个问题,当我从另一个数组中删除对象时,会从所有对象中删除值 1) 下面是我的结束语iOS swift中所有对象的引用相同,ios,arrays,swift,closures,Ios,Arrays,Swift,Closures,在swift 4.2中,我在处理两个数组对象时遇到了这个问题,当我从另一个数组中删除对象时,会从所有对象中删除值 1) 下面是我的结束语 func GetChatBotData(completion: @escaping (_ result: ChatV_1_Model) -> Void) { var ChatBotData : ChatV_1_Model! = nil ApiHelper.sharedSession.postLoacl("http://localhost
func GetChatBotData(completion: @escaping (_ result: ChatV_1_Model) -> Void) {
var ChatBotData : ChatV_1_Model! = nil
ApiHelper.sharedSession.postLoacl("http://localhost:3000/posts/", postData: NSDictionary(), methodtype: Constant.API.httpGet) { (isError, data, errorDescription) in
DispatchQueue.main.async(execute: {
if isError == false {
ChatBotData = ChatV_1_Model.init(fromDictionary: data!)
completion(ChatBotData)
}
else {
//completion("Error to get result" as AnyObject)
completion(ChatBotData)
}
})
}
}
现在在我的控制器里
var PKComponents = [Chatbot_V_1_DataModel]()
var ChatMessages = [Chatbot_V_1_DataModel]()
override func viewDidLoad() {
super.viewDidLoad()
GetChatBotData() {(result: ChatbotV_1_Model!) in
print("Call Plans: \(result!)")
self.PKComponents = result.data
self.ChatMessages = result.data
self.ChatMessages[0].component.removeAll()
}
在Viewdidload中,我正在从self.ChatMessages数组中删除对象,但它也会从所有对象(如PKComponents和result.data)中删除对象
注意:我看到结果的引用与PKComponents和Chatmessages相同
如何解决这个问题?这是深度复制的问题。要么编写一个完整的初始值设定项来复制所有内容,然后创建一个新对象并使用它,而不仅仅是赋值。或者使用struct而不是class。但作为一种快速修复方法,您只能显式复制组件数组,如下所示:
self.PKCOMPONENTS = results.data
self.PKCOMPONENTS.components = Array(results.data.components)
你有两个建议 1-深度复制。
2-使用
struct
而不是类,因为它的值类型为
对于深度复制,这是一个简单的例子,
当您将某些内容分配给新实例时,请使用这种方式
// Deep copy
var foo = Foo()
var otherFoo = Foo(foo)
而不是这个
var fee = foo // shallow copy still the same referance
注意:这由swift处理,您不必向类中添加任何初始化
是您要从中删除的组件,而不是要从组件
中删除的组件 准确点阵列
- swift中的数组实现使用的是
,它是 值类型而不是对象类型,数组所包含的内容,即Struct
Chatbot\u V\u 1\u数据模型的对象也可能是一个类,因此 数组中的元素是对类型为的对象的引用 Chatbot_V_1_数据模型
- 解决这个问题的方法是使用
定义为Chatbot\u V\u 1\u数据模型
因此,是一种值类型,或通过制作 您可以创建数组,然后在修改闭包时在闭包中使用该副本struct
var copie = arr.map{$0.mutableCopy()}
更好的是:
var PKComponents = [Chatbot_V_1_DataModel]()
var ChatMessages = [Chatbot_V_1_DataModel]()
override func viewDidLoad() {
super.viewDidLoad()
var copie = arr.map{$0.mutableCopy()} // use this copy now elsewhere!!!
GetChatBotData() {(result: ChatbotV_1_Model!) in
print("Call Plans: \(result!)")
self.PKComponents = result.data
self.ChatMessages = result.data
self.ChatMessages[0].component.removeAll()
}
下面是一个简化的示例,我可以在其中重现您的问题:
class Component {
}
class SomeData {
var components: [Component]
init(components : [Component]) {
self.components = components
}
}
class Result {
var data: [SomeData]
init(data: [SomeData]) {
self.data = data
}
}
let someData = SomeData(components: [Component()])
let result = Result(data: [someData])
//problem begins here
let pkCompent = result.data
var chatMsgs = result.data
print(pkCompent[0].components.count)
chatMsgs[0].components.removeAll()
print(pkCompent[0].components.count)
为了避免引用问题,请将SomeData转换为struct
一种选择是使用
struct
而不是class
。在哪里使用class作为我的闭包也在controller中为什么要声明局部变量而不是将其放入分派闭包中?我也尝试过这种方法,但问题是相同的,该结果和新对象具有相同的内存引用。我不了解您,因为我使用的是自定义类型数组。如何初始化它,无论您是否具有自定义对象数组。只要它是一个数组,就可以这样初始化。results.data也是一个数组,因此您可以使用它初始化另一个数组。是的,我尝试过self.PKComponents=[Chatbot_V_1_DataModel](result.data),但具有相同的引用
struct SomeData {
var components: [Component]
init(components : [Component]) {
self.components = components
}
}