【问题标题】:Saving Array with NSCoding使用 NSCoding 保存数组
【发布时间】:2015-08-16 06:13:45
【问题描述】:

我有一个小应用程序,它有一些保存功能。我有一个名为:Closet:

的数据模型类
class Department: NSObject, NSCoding {
   var deptName = ""
   var managerName = ""

   var Task: [Assignment]?   // <----- assignment class is in example 2

   func encodeWithCoder(aCoder: NSCoder) {

    aCoder.encodeObject(deptName, forKey: "deptName")
    aCoder.encodeObject(managerName, forKey: "mngName")
   // aCoder.encodeObject(Task, forKey: "taskArray")

}

  required init(coder aDecoder: NSCoder) {

     super.init()

    course = aDecoder.decodeObjectForKey("deptName") as! String
    instructor = aDecoder.decodeObjectForKey("mngName") as! String
   // Task = aDecoder.decodeObjectForKey("tasKArray") as? [Assignment]

}

override init() {
    super.init()
}

}

这是主控制器数据模型,在第一个 View Controller 中,用户可以点击“+”按钮添加部门名称和经理名称。问题不在于保存它,因为我使用 NSKeyedArchive 成功保存它并在应用程序启动时将其加载回来。

问题:

我想在这个名为 Assignment 的数据模型 Department 上添加一个分配数组,其中包含一个 title 和一个 notes 变量。这是分配的数据模型:

Assignment.swift

class Assignment: NSObject, NSCoding {
     var title = ""
     var notes = ""

      func encodeWithCoder(aCoder: NSCoder) {

    // Methods
    aCoder.encodeObject(title, forKey: "Title")
    aCoder.encodeObject(notes, forKey: "notepad")

}

required init(coder aDecoder: NSCoder) {


// Methods
    title = aDecoder.decodeObjectForKey("Title") as! String
    notes = aDecoder.decodeObjectForKey("notepad") as! String

    super.init()
}

override init() {
    super.init()
}


 }

所以我基本上想要实现的是一个应用程序,其中用户输入具有不同经理姓名的不同部门,现在在我的应用程序中工作,但在一个部门内,用户可以单击“+”按钮添加分配标题和注释部分,点击后可以编辑,我以后可以处理。这些任务因部门而异。

我最大的问题是实现这个功能。我似乎无法正常工作。

我希望这个数组分配属性成为部门类的一部分,这样每个单元格都可以有自己的待办事项列表。任何帮助肯定会帮助我很多。谢谢:)

【问题讨论】:

  • 对这个小问题有什么帮助而不导致核心数据?

标签: swift ios8 nscoding data-persistence


【解决方案1】:

您正确使用了NSCoder,但大小写有两个错误。第一个错误影响应用程序的功能,第二个错误是风格错误。您使用密钥"taskArray"Task 进行了编码,但您尝试使用密钥"tasKArray" 对其进行解码。如果您在后者中修复大写 K,那么您的代码将起作用。

第二个大写错误是一个文体错误:Task,就像 Swift 中的所有属性一样,应该用 lowerCamelCase (llamaCase) 编写。

一定要密切注意缩进。在编程中,我们遵循特殊的缩进规则来帮助使代码清晰。以下是正确大小写和缩进的更正代码:

class Department: NSObject, NSCoding {
    var deptName = ""
    var managerName = ""

    var task: [Assignment]?

    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(deptName, forKey: "deptName")
        aCoder.encodeObject(managerName, forKey: "mngName")
        aCoder.encodeObject(task, forKey: "taskArray")
    }

    required init(coder aDecoder: NSCoder) {
        super.init()

        course = aDecoder.decodeObjectForKey("deptName") as! String
        instructor = aDecoder.decodeObjectForKey("mngName") as! String
        task = aDecoder.decodeObjectForKey("taskArray") as? [Assignment]
    }

    override init() {
        super.init()
    }
}

class Assignment: NSObject, NSCoding {
    var title = ""
    var notes = ""

    func encodeWithCoder(aCoder: NSCoder) {
        // Methods
        aCoder.encodeObject(title, forKey: "Title")
        aCoder.encodeObject(notes, forKey: "notepad")
    }

    required init(coder aDecoder: NSCoder) {
        // Methods
        title = aDecoder.decodeObjectForKey("Title") as! String
        notes = aDecoder.decodeObjectForKey("notepad") as! String

        super.init()
    }

    override init() {
        super.init()
    }
}

【讨论】:

  • 我会尝试重构我的代码,看看它是否有效。但基本上我想要实现的是将数据保存在数据中。带有子单元格的父单元格在点击父单元格时,它会显示带有“分配”类的子单元格作为其数据模型来保存“标题”和“注释”
【解决方案2】:

为 Swift 5 / Xcode 版本 12.4 (12D4e) 更新

感谢 Tone416 上面的示例——由于协议和方法发生了变化,我已经为 Swift 5 重新设计了它。我还提供了一个简单的测试来证明这一点,因此您应该能够将其剪切并粘贴到操场上并运行它。


import Foundation

class Department: NSObject, NSCoding {
    var deptName = ""
    var managerName = ""
    
    var task: [Assignment]?
    
    func encode(with coder: NSCoder) {
        coder.encode(deptName, forKey: "deptName")
        coder.encode(managerName, forKey: "mngName")
        coder.encode(task, forKey: "taskArray")
    }
    
    required init(coder aDecoder: NSCoder) {
        super.init()
        
        deptName = aDecoder.decodeObject(forKey: "deptName") as! String
        managerName = aDecoder.decodeObject(forKey: "mngName") as! String
        task = aDecoder.decodeObject(forKey: "taskArray") as? [Assignment]
    }
    
    override init() {
        super.init()
    }
    
    convenience init(deptName: String, managerName: String, task: [Assignment]?) {
        self.init()
        
        self.deptName = deptName
        self.managerName = managerName
        self.task = task
    }
}

class Assignment: NSObject, NSCoding {
    var title = ""
    var notes = ""
    
    func encode(with coder: NSCoder) {
        // Methods
        coder.encode(title, forKey: "Title")
        coder.encode(notes, forKey: "notepad")
    }
    
    required init(coder aDecoder: NSCoder) {
        // Methods
        title = aDecoder.decodeObject(forKey: "Title") as! String
        notes = aDecoder.decodeObject(forKey: "notepad") as! String
        
        super.init()
    }
    
    override init() {
        super.init()
    }
    
    convenience init(title: String, notes: String) {
        self.init()
        
        self.title = title
        self.notes = notes
    }
}

// Create some data for testing
let assignment1 = Assignment(title: "title 1", notes: "notes 1")
let assignment2 = Assignment(title: "title 2", notes: "notes 2")
let myDepartment = Department(deptName: "My Dept", managerName: "My Manager", task: [assignment1, assignment2])

// Try archive and unarchive
do {
    // Archive
    let data = try NSKeyedArchiver.archivedData(withRootObject: myDepartment, requiringSecureCoding: false)
    print ("Bytes in archive: \(data.count)")
    
    // Unarchive
    let obj = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as! Department
    
    // Print the contents of the unarchived object
    print("Department: \(obj.deptName)    Manager: \(obj.managerName)")
    if let task = obj.task {
        for i in 0...task.count-1 {
            print("Task: \(task[i].title) \(task[i].notes)")
        }
    }
    
} catch {
    
    let nsError = error as NSError
    fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}

享受

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-31
    • 2017-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多