繁体   English   中英

iOS Swift中所有对象的参考相同

[英]Same reference for all the objects in iOS swift

在Swift 4.2中,我在处理两个数组对象时面临问题,当我从另一个数组中删除对象时,值将从所有对象中删除。

1)下面是我的关闭

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相同。

如何解决呢?

这是简化的示例,在这里我可以重现您的问题:

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 SomeData {
    var components: [Component]
    init(components : [Component]) {
        self.components = components
    }
}

这是深度复制的问题。 您可以编写一个完整的初始化程序来复制所有内容并创建一个新对象,然后使用它而不是仅仅进行赋值。 或者使用struct而不是class。 但是,作为一种快速修复,您可以像下面这样显式地仅复制组件数组:

self.PKCOMPONENTS = results.data
self.PKCOMPONENTS.components = Array(results.data.components)

您有2条建议。

1-深复制。
2-由于其值类型,请使用struct而不是class。

如果是深层复制,这是一个简单的示例,当您使用这种方式向新实例分配内容时。

// Deep copy
var foo = Foo()
var otherFoo  = Foo(foo)

而不是这个。

var fee = foo // shallow copy still the same referance 

注意:这是通过快速处理的,您不必在类中添加任何init。

  • component是您要从中删除的component ,而不是精确的Array

  • swift中的数组实现使用的是值类型而不是对象类型的Struct ,但是数组所持有的内容,即Chatbot_V_1_DataModel对象Chatbot_V_1_DataModel可能是一个类,因此,数组中保存的元素是对类型对象的引用Chatbot_V_1_DataModel。

  • 解决此问题的方法是将Chatbot_V_1_DataModel定义为struct从而将Chatbot_V_1_DataModel定义为值类型,或者通过对数组进行深拷贝,然后在修改时在闭包中使用该拷贝。

我说的是这些方面的东西:

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()
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM