Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS swift中所有对象的引用相同_Ios_Arrays_Swift_Closures - Fatal编程技术网

iOS swift中所有对象的引用相同

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

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


如何解决这个问题?

这是深度复制的问题。要么编写一个完整的初始值设定项来复制所有内容,然后创建一个新对象并使用它,而不仅仅是赋值。或者使用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
    }
}