ios 无法识别的选择器在归档数据时发送到实例(NSCoding)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22168753/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 23:38:08  来源:igfitidea点击:

Unrecognized selector sent to instance while archiving data (NSCoding)

iosnsdataunrecognized-selector

提问by SteBra

-(void)transformObjects:(NSMutableArray*)array key:(NSString*)key
{
    NSMutableArray* archiveArray = [[NSMutableArray alloc]initWithCapacity:array.count];

    for (Furniture *furniture in array) {

        // The error occurs on the line below
        NSData *furnitureEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:furniture];
        [archiveArray addObject:furnitureEncodedObject];
    }

    NSUserDefaults *userData = [NSUserDefaults standardUserDefaults];
    [userData setObject:archiveArray forKey:key];
}

Error log:

错误日志:

2014-03-04 10:55:27.881 AppName[10641:60b] -[Furniture encodeWithCoder:]: unrecognized selector sent to instance 0x15d43350

I have no idea why do I get "unrecognized selector sent to instance" when trying to archive an object.

我不知道为什么在尝试存档对象时会收到“无法识别的选择器发送到实例”。

回答by Grzegorz Krukowski

You need to implement NSCoding protocol inside your Furniture object:

您需要在您的 Furniture 对象中实现 NSCoding 协议:

- (void)encodeWithCoder:(NSCoder *)aCoder{
  [aCoder encodeObject:self.yourpoperty forKey:@"PROPERTY_KEY"];
}

-(id)initWithCoder:(NSCoder *)aDecoder{
  if(self = [super init]){
    self.yourpoperty = [aDecoder decodeObjectForKey:@"PROPERTY_KEY"];
  }
  return self;
}

Basically you specify what should be written (encoded) and read from a file (decoded). Usually for each property you want to store in a file, you make same as I did here in an example.

基本上,您指定应该写入(编码)和从文件中读取(解码)的内容。通常对于您想要存储在文件中的每个属性,您可以像我在示例中所做的那样进行设置。

回答by Zorayr

You'll need to implement NSCoding- here is an example with an object called SNStockthat has two string properties, tickerand name:

您需要实现NSCoding- 这是一个名为对象的示例,该对象SNStock具有两个字符串属性,ticker并且name

import Foundation

class SNStock: NSObject, NSCoding
{
  let ticker: NSString
  let name: NSString

  init(ticker: NSString, name: NSString)
  {
    self.ticker = ticker
    self.name = name
  }

  //MARK: NSCoding

  required init(coder aDecoder: NSCoder) {
    self.ticker = aDecoder.decodeObjectForKey("ticker") as! NSString
    self.name = aDecoder.decodeObjectForKey("name") as! NSString
  }

  func encodeWithCoder(aCoder: NSCoder) {
    aCoder.encodeObject(ticker, forKey: "ticker")
    aCoder.encodeObject(name, forKey: "name")
  }

  //MARK: NSObjectProtocol

  override func isEqual(object: AnyObject?) -> Bool {
    if let object = object as? SNStock {
      return self.ticker == object.ticker &&
        self.name == object.name
    } else {
      return false
    }
  }

  override var hash: Int {
    return ticker.hashValue
  }
}

回答by Hardik Thakkar

For Swift 4.1 (tested code)

对于 Swift 4.1(测试代码)

import UIKit
import SwiftyJSON

class UserObject: NSObject, NSCoding {
    var username: String? = ""
    var userID: String? = ""
    var user_email: String? = ""
    var name: String? = ""
    var age: String? = ""
    var gender: String? = ""

    override init() {
        super.init()
    }

    init(dictionary: JSON) {
        //User data initialize...
        username = dictionary["username"].stringValue
        userID = dictionary["iUserID"].stringValue
        user_email = dictionary["email"].stringValue
        name = dictionary["name"].stringValue
        age = dictionary["age"].stringValue
        gender = dictionary["gender"].stringValue
    }

    required public init(coder aDecoder: NSCoder) {
        username = aDecoder.decodeObject(forKey: "username") as? String
        userID = aDecoder.decodeObject(forKey: "iUserID") as? String
        user_email = aDecoder.decodeObject(forKey: "email") as? String
        name = aDecoder.decodeObject(forKey: "name") as? String
        age = aDecoder.decodeObject(forKey: "age") as? String
        gender = aDecoder.decodeObject(forKey: "gender") as? String
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(username, forKey: "username")
        aCoder.encode(userID, forKey: "iUserID")
        aCoder.encode(user_email, forKey: "email")
        aCoder.encode(name, forKey: "name")
        aCoder.encode(age, forKey: "age")
        aCoder.encode(gender, forKey: "gender")
    }
}

Note : NSCoding protocol is important

注意:NSCoding 协议很重要

回答by Wain

You have a custom class Furniturewhich you are trying to archive with NSKeyedArchiver. In order for this to work, the Furnitureclass needs to conform to the < NSCoding >protocol. Which means implementing the encodeWithCoder:and initWithCoder:methods.

您有一个自定义类Furniture,您正尝试使用NSKeyedArchiver. 为了使其工作,Furniture该类需要符合< NSCoding >协议。这意味着实现encodeWithCoder:initWithCoder:方法。

Currently you don't implement these methods. You need to add them.

目前您没有实现这些方法。您需要添加它们。

回答by Benjamin Clanet

I think your Furniture class does not implement the NSCoding protocol.

我认为您的 Furniture 类没有实现 NSCoding 协议。