这就是我设置数据结构的方式:
class Commit: NSObject, NSCoding {
//MARK: Properties
var contents : String
var repeatStatus : Bool
var completionStatus : Bool
//MARK: Initialization
init(contents: String, repeatStatus: Bool, completionStatus: Bool) {
self.contents = contents
self.repeatStatus = repeatStatus
self.completionStatus = completionStatus
super.init()
}
//MARK: NSCoding
func encodeWithCoder(aCoder: NSCoder){
aCoder.encodeObject(contents, forKey: PropertyKey.contentsKey)
aCoder.encodeObject(repeatStatus, forKey: PropertyKey.repeatStatusKey)
aCoder.encodeObject(completionStatus, forKey: PropertyKey.completionStatusKey)
}
required convenience init?(coder aDecoder: NSCoder) {
let contents = aDecoder.decodeObjectForKey(PropertyKey.contentsKey) as! String
let repeatStatus = aDecoder.decodeObjectForKey(PropertyKey.repeatStatusKey) as! Bool
let completionStatus = aDecoder.decodeObjectForKey(PropertyKey.completionStatusKey) as! Bool
self.init(contents: contents, repeatStatus: repeatStatus, completionStatus: completionStatus)
}
}
class ToDoList: NSObject, NSCoding {
//MARK: Properties
var commitArray : [Commit]
var date : Int
// MARK: Archiving Paths
static let DocumentsDirectory = NSFileManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
static let ArchiveURL = DocumentsDirectory.URLByAppendingPathComponent("toDoList")
//MARK: Initialization
override init(){
let defaultCommit = Commit(contents: "", repeatStatus: false, completionStatus: false)
self.date = dateTodayAsInt
self.commitArray = [defaultCommit, defaultCommit, defaultCommit]
super.init()
}
init(commitArray: [Commit], date: Int) {
self.date = date
self.commitArray = commitArray
super.init()
}
//MARK: NSCoding
func encodeWithCoder(aCoder: NSCoder){
aCoder.encodeObject(commitArray, forKey: PropertyKey.commitArrayKey)
aCoder.encodeObject(date, forKey: PropertyKey.dateKey)
}
required convenience init?(coder aDecoder: NSCoder) {
let commitArray = aDecoder.decodeObjectForKey(PropertyKey.commitArrayKey) as! [Commit]
let date = aDecoder.decodeObjectForKey(PropertyKey.dateKey) as! Int
self.init(commitArray: commitArray, date: date)
}
}
func findIndexOfActiveToDoList(allToDoLists: [ToDoList]) -> Int {
var j = Int(floor(Double((allToDoLists.count/2))))
var count = 0
repeat {
count += 1
if allToDoLists[j].date < dateTodayAsInt {
j = Int(j + j/2)
} else if allToDoLists[j].date > dateTodayAsInt {
j = Int(j - j/2)
} else { return j }
} while count < Int(sqrt(Double(allToDoLists.count/2)))
print(j)
return j }
// MARK: Types
struct PropertyKey {
static let contentsKey = "contents"
static let repeatStatusKey = "repeatStatus"
static let completionStatusKey = "completionStatus"
static let commitArrayKey = "commitArray"
static let dateKey = "date"
}
var toDoList = [Commit]()
var allToDoLists = [ToDoList]()
稍后,当我想更新allToDoLists数组时,如下所示:
FirstCommitTextField.text! = allToDoLists[findIndexOfActiveToDoList(allToDoLists)].commitArray[0].contents
无论我做什么,只要我设置:
SecondCommitTextField.text! = allToDoLists[findIndexOfActiveToDoList(allToDoLists)].commitArray[1].contents
提交数组的第一个元素的content属性也会更改。我已经运行应用程序,打印注释在设置提交数组的第二个元素的内容属性之前和之后打印提交数组的第一个元素的内容属性 - 只是设置第二个属性以某种方式更改了第一个元素。
这使我得出结论,以某种方式设置数组中元素的值也会改变该数组中第二个元素的值。是这样的吗?如果是,如何避免/规避这一点?
提前致谢!
答案 0 :(得分:0)
我怀疑你打算写:
allToDoLists[findIndexOfActiveToDoList(allToDoLists)].commitArray[0].contents =
FirstCommitTextField.text!
allToDoLists[findIndexOfActiveToDoList(allToDoLists)].commitArray[1].contents =
SecondCommitTextField.text!
如果是这种情况,那么您看到第二次更新会影响commitArray[0]
内容的原因是您初始化了ToDoList.commitArray
:
self.commitArray = [defaultCommit, defaultCommit, defaultCommit]
你的Commit
是一个常规类而不是struct,所以它是通过引用传递的(参见:structure vs class in swift language)。因此,当您更改commitArray[0].contents
时,您会在commitArray[1].contents
和commitArray[2].contents
中看到相同的值。
请注意,对象引用由NSCoder
保留,因此如果它们在序列化之前是同一个对象,则在反序列化后它们将是相同的。
您应该使用默认参数初始化新实例,而不是重新使用let defaultCommit = Commit(...)
。例如,为Commit
添加便利初始值设定项:
convenience override init() {
self.init(contents: "", repeatStatus: false, completionStatus: false)
}
(override
是必需的,因为NSObject
已经声明了无参数init
。)
然后使用它:
self.commitArray = [Commit(), Commit(), Commit()]