gpt4 book ai didi

arrays - 数组的副本正在改变原件

转载 作者:搜寻专家 更新时间:2023-11-01 06:12:14 25 4
gpt4 key购买 nike

我有两个 Controller 。第一个 Controller 从服务器加载列表并创建自定义对象列表 WordList

class WordList {

let name: String
let releaseDate: Date
var words: [String]
let multiplier: Int

...
}

在第一个屏幕上,用户可以选择在继续之前选择列表。在下一个 Controller 上,从随机列表中选择一个随机词。单词出现后,当用户与之交互时,它会被移除。一旦用户开始交互,就会选择一个新词,直到不再有为止。如果我回到主 Controller 并选择我刚刚使用的相同列表,该列表将为空。这就是我发送所选项目的方式。

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? WordController {
var wordLists = [WordList]()

for index in tableView.indexPathsForSelectedRows! {
wordLists.append(lists[index.row]) // lists is a class property that is a WordList array.
}

// This was my first attempt. Values were copied but removed from this controller.
// for wordList in wordLists {
// destination.wordLists.append(wordList)
// }

// destination.wordLists = wordLists

// This was my second attempt. Values were also copied but removed from this controller.
destination.wordLists.append(contentsOf: wordLists)
}
}

我知道我必须传递列表的引用而不是实际复制它,但我不认为如果我通过复制第一个数组的值来填充第二个数组,它会如何工作。

除了在每次用户返回屏幕时重新加载第一个 Controller 之外,我如何才能让用户重新使用已清除的列表?

最佳答案

你说:

I understand that I must be passing a reference of the list instead of actually copying it ...

不,你正在传递一个新数组。

... but I didn't think that that would be how it would work if I'm populating the second array by copying values from the first.

不幸的是,您不是从第一个数组“复制值”,而是将 WordList 引用从第一个数组复制到第二个数组。归根结底,问题不在于值类型 Array,而在于引用类型 WordList

WordList 是一个引用类型,因为它是一个。因此,当您从一个数组中获取对 WordList 的引用并将其添加到另一个数组时,第二个数组仍将引用相同的 WordList 实例。

如果您不希望对其他数组实例的操作影响原始实例,您可以:

  • WordList 从引用类型(class)更改为值类型(struct):

    struct WordList {
    let name: String
    let releaseDate: Date
    var words: [String]
    let multiplier: Int
    }
  • 如果您真的需要使用,请编写您自己的copy 方法来返回一个新实例。例如,您可能符合 NSCopying 并编写 copy(with:):

    extension WordList: NSCopying {
    func copy(with zone: NSZone? = nil) -> Any {
    return WordList(name: name, releaseDate: releaseDate, words: words, multiplier: multiplier)
    }
    }

    然后当您构建新数组时,附加副本而不是对原始实例的引用:

    for index in tableView.indexPathsForSelectedRows! {
    wordLists.append(lists[index.row].copy() as! WordList)
    }

如果您不喜欢 NSCopyingcopy 引入了笨拙的 Any 返回类型,您也可以定义您的 copy 方法,甚至编写您自己的 Copying 协议(protocol),例如:

protocol Copying {
associatedtype ObjectType = Self
func copy() -> ObjectType
}

extension WordList: Copying {
func copy() -> WordList {
return WordList(name: name, releaseDate: releaseDate, words: words, multiplier: multiplier)
}
}

然后您可以执行以下操作,无需转换:

for index in tableView.indexPathsForSelectedRows! {
wordLists.append(lists[index.row].copy())
}

关于arrays - 数组的副本正在改变原件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53483730/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com