Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/98.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-使用NSKeyedArchiver保存用户数据,在转换到NSArray时出错_Ios_Arrays_Swift_Nsuserdefaults_Nskeyedarchiver - Fatal编程技术网

Ios Swift-使用NSKeyedArchiver保存用户数据,在转换到NSArray时出错

Ios Swift-使用NSKeyedArchiver保存用户数据,在转换到NSArray时出错,ios,arrays,swift,nsuserdefaults,nskeyedarchiver,Ios,Arrays,Swift,Nsuserdefaults,Nskeyedarchiver,所以我有一个自定义对象数组。当我尝试将阵列保存为NSUserDefault时,我必须将它们存档。以下是我为存档自定义对象数组所做的操作: override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { //3 var allMessages = defaults.objectForKey(UserDefaultsMesssageKey) as! [A

所以我有一个自定义对象数组。当我尝试将阵列保存为NSUserDefault时,我必须将它们存档。以下是我为存档自定义对象数组所做的操作:

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    //3

    var allMessages = defaults.objectForKey(UserDefaultsMesssageKey) as! [AddMessageViewController.harassText]
    var aMessage = AddMessageViewController.harassText(phoneNumber: 0, message: "1", frequency: 1, active: 1)
    allMessages.append(aMessage)
    saveMessage(allMessages)


    return (allMessages.count)
}

func archiveMessage(message:[AddMessageViewController.harassText]) -> NSData {
    let archivedObject = NSKeyedArchiver.archivedDataWithRootObject(message as NSArray)
    return archivedObject
}
func saveMessage(messages: [AddMessageViewController.harassText]) {
    let archivedObject = archiveMessage(messages)
    defaults.setObject(archivedObject, forKey: UserDefaultsMesssageKey)
    defaults.synchronize()
}
func retrieveData()-> [AddMessageViewController.harassText]? {
    if let unarchiveObject = NSUserDefaults.standardUserDefaults().objectForKey(UserDefaultsMesssageKey) as? NSData {
        return NSKeyedUnarchiver.unarchiveObjectWithData(unarchiveObject) as? [AddMessageViewController.harassText]
    }
    return nil
}
流程是:

  • 在saveMessage调用时,传入自定义数组以进行存档。以下是GDB对阵列的看法。您可以看到它是一个数组,其中包含一个class对象

    ([Harass\u Your\u Kate.AddMessageViewController.harassText])$R0=1值{
    [0]=0x00007fa5ab409600{
    ObjectiveC.NSObject={
    isa=Harass\u您的\u Kate.AddMessageViewController.harassText
    }
    电话号码=0
    message=“1”
    频率=1
    活动=1
    }
    }

  • 数组被传递到archiveMessage中。NSKeyedArchiver方法上的代码立即失败。错误消息如下所示:

    [_TtCC16Harass_Your_Kate24AddMessageViewController10harassText encodeWithCoder:]: unrecognized selector sent to instance 0x7fa5ab409600
    
    2016-07-15 16:31:26.019骚扰你的凯特[5858:7847495]*-[NSKeyedArchiver DEALOC]:警告:NSKeyedArchiver未完成交易-调用了它。 2016-07-15 16:31:26.023骚扰你的凯特[5858:7847495]*由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'-[\uTTCC16haras\uKate24addMessageViewController10harassText encodeWithCoder:]:未识别的选择器发送到实例0x7fa5ab409600

  • 我感谢所有的帮助,提前谢谢你

    编辑:以下是我的对象的定义:

    class Text : NSObject {
        var phoneNumber = 0             //Text address to send to
        var message: String = ""        //Message to be sent
        var frequency = 24              //Number of hours between messages (usually a multiple of 24 - 24 = daily)
        var active = 0                  // 0 if cancelled, 1 if active
    
        init(phoneNumber: Int, message: String, frequency: Int, active: Int ){
            self.phoneNumber = phoneNumber
            self.message = message
            self.frequency = frequency
            self.active = active
        }
    }
    

    NSKeyedArchiver
    利用您必须提供的方法,通过遵守
    NSCoding
    协议来序列化对象。它不能自动推断如何保存自定义类;您必须按照以下方式自行实施:

    class Text : NSObject, NSCoding {
        var phoneNumber = 0             //Text address to send to
        var message: String = ""        //Message to be sent
        var frequency = 24              //Number of hours between messages (usually a multiple of 24 - 24 = daily)
        var active = 0                  // 0 if cancelled, 1 if active
    
        init(phoneNumber: Int, message: String, frequency: Int, active: Int ){
            self.phoneNumber = phoneNumber
            self.message = message
            self.frequency = frequency
            self.active = active
        }
    
        required init?(coder aDecoder: NSCoder) {
            phoneNumber = aDecoder.decodeInteger(forKey: "phoneNumber")
            message = aDecoder.decodeObject(forKey: "message") as! String
            frequency = aDecoder.decodeInteger(forKey: "frequency")
            active = aDecoder.decodeInteger(forKey: "active")
        }
    
        func encode(with aCoder: NSCoder) {
            aCoder.encode(phoneNumber, forKey: "phoneNumber")
            aCoder.encode(message, forKey: "message")
            aCoder.encode(frequency, forKey: "frequency")
            aCoder.encode(active, forKey: "active")
        }
    }
    

    如您所见,初始值设定项从编码器读取并创建和实例,而
    encode
    方法将相关信息保存到编码器。在这样一个简单的类中,它们的实现可能看起来很明显,但在更复杂的自定义类型中,需要做出非平凡的编码决策。

    我们需要了解自定义对象的NSCoding方法。(
    initWithCoder
    encodeWithCoder
    )。我没有这两样东西。那就是问题所在。然后向我们展示自定义类的定义。(编辑您的问题以添加代码,不要将其发布在评论中。)如果您尝试对容器进行编码,则不能使用
    NSCoding
    将“对象图”转换为
    NSData
    ,除非每个对象都符合NSCoding(这意味着必须实现
    initWithCoder
    encodeWithCoder
    )(如数组或字典)对于对象,容器中的所有对象都必须符合
    NSCoding
    ,否则它将不起作用。@Duncac感谢您的帮助。我在编辑中包含了自定义类的定义。我对NSCoding的含义非常困惑,因为我以前从未使用过,当然也没有在保存自定义类数组的上下文中使用过。但是再次感谢您抽出时间来帮助我。我期待再次收到您的来信谢谢!这非常有效。我还在使用CoreData实现它,它似乎更易于存储自定义信息