我想保存一个NSMutableDictionary对象NSUserDefaults.键类型NSMutableDictionary是NSString,值类型是NSArray,它包含实现的对象列表NSCoding.每份文件,NSString和NSArray两者都符合NSCoding.
我收到此错误:
[NSUserDefaults setObject:forKey:]:尝试插入类NSCFDictionary的非属性值....
有谁知道如何使用Xcode 9 GM修复此错误?我正在开发一个使用Xcode 8.3制作的应用程序,部署目标是针对iOS 9.3,我之前从未遇到过这个问题.我在这里或Apple论坛上没有找到任何信息:(
编辑:当我将WKWebView放入界面构建器时出现此错误,而不是以编程方式使用它.

编辑2:嗯,这最终不是一个错误,请参阅下面的Quinn的答案,以获得有关此行为的更多信息.感谢他的解释.
我目前正在尝试将自定义Swift类保存到NSUserDefaults.这是我的Playground的代码:
import Foundation
class Blog : NSObject, NSCoding {
var blogName: String?
override init() {}
required init(coder aDecoder: NSCoder) {
if let blogName = aDecoder.decodeObjectForKey("blogName") as? String {
self.blogName = blogName
}
}
func encodeWithCoder(aCoder: NSCoder) {
if let blogName = self.blogName {
aCoder.encodeObject(blogName, forKey: "blogName")
}
}
}
var blog = Blog()
blog.blogName = "My Blog"
let ud = NSUserDefaults.standardUserDefaults()
ud.setObject(blog, forKey: "blog")
Run Code Online (Sandbox Code Playgroud)
当我运行代码时,我收到以下错误
执行被中断,原因:信号SIGABRT.
在最后一行(ud.setObject...)
在带有消息的应用程序中,相同的代码也会崩溃
"属性列表格式无效:200(属性列表不能包含'CFType'类型的对象)"
有人可以帮忙吗?我在Maverick上使用Xcode 6.0.1.谢谢.
我创建了一个符合NSCoding的Swift类.(Xcode 6 GM,Swift 1.0)
import Foundation
private var nextNonce = 1000
class Command: NSCoding {
let nonce: Int
let string: String!
init(string: String) {
self.nonce = nextNonce++
self.string = string
}
required init(coder aDecoder: NSCoder) {
nonce = aDecoder.decodeIntegerForKey("nonce")
string = aDecoder.decodeObjectForKey("string") as String
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeInteger(nonce, forKey: "nonce")
aCoder.encodeObject(string, forKey: "string")
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我打电话给...
let data = NSKeyedArchiver.archivedDataWithRootObject(cmd);
崩溃给了我这个错误.
2014-09-12 16:30:00.463 MyApp[30078:60b] *** NSForwarding: warning: object 0x7a04ac70 of class '_TtC8MyApp7Command' does not implement methodSignatureForSelector: -- trouble …Run Code Online (Sandbox Code Playgroud) 我在Playground使用Swift 3,Xcode 8.0:
import Foundation
class Person: NSObject, NSCoding {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
required convenience init(coder aDecoder: NSCoder) {
let name = aDecoder.decodeObject(forKey: "name") as! String
let age = aDecoder.decodeObject(forKey: "age") as! Int
self.init(
name: name,
age: age
)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
aCoder.encode(age, forKey: "age")
}
}
Run Code Online (Sandbox Code Playgroud)
创建Person数组
let newPerson = Person(name: "Joe", age: 10)
var people = [Person]() …Run Code Online (Sandbox Code Playgroud) 我有一个iOS 7应用程序,它将自定义对象作为文件保存到应用程序的iCloud Docs文件夹中.为此,我使用了NSCoding协议.
@interface Person : NSObject <NSCoding>
@property (copy, nonatomic) NSString *name
@property (copy, nonatomic) NSString *lastName
@end
Run Code Online (Sandbox Code Playgroud)
对象序列化在iOS 7版本的应用程序中完美运行:
initWithCoder 和 encodeWithCoder
[NSKeyedArchiver archivedDataWithRootObject:person]
person = NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)theData]
但我需要将此应用程序移至iOS 8,此类将以swift编码,并为此iOS应用程序的新版本重新命名.
class PersonOldVersion: NSObject, NSCoding {
var name = ""
var lastName = ""
}
Run Code Online (Sandbox Code Playgroud)
当我尝试取消归档该对象时,我收到以下错误:
*** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (Person)'
Run Code Online (Sandbox Code Playgroud)
我已经尝试将swift类'PersonOldVersion'重命名为原始类名('Person'),但仍然失败.
如何解码原始类不可用的对象?
我有一个符合NSCoding协议的简单对象.
import Foundation
class JobCategory: NSObject, NSCoding {
var id: Int
var name: String
var URLString: String
init(id: Int, name: String, URLString: String) {
self.id = id
self.name = name
self.URLString = URLString
}
// MARK: - NSCoding
required init(coder aDecoder: NSCoder) {
id = aDecoder.decodeObject(forKey: "id") as? Int ?? aDecoder.decodeInteger(forKey: "id")
name = aDecoder.decodeObject(forKey: "name") as! String
URLString = aDecoder.decodeObject(forKey: "URLString") as! String
}
func encode(with aCoder: NSCoder) {
aCoder.encode(id, forKey: "id")
aCoder.encode(name, forKey: "name")
aCoder.encode(URLString, forKey: …Run Code Online (Sandbox Code Playgroud) 我正在学习NSSecureCodingApple在iOS 6中引入的协议.
根据我的理解,到目前为止,只要一个类对自身的实例进行编码/解码,就应该使用它,以防止替换攻击.
我想知道在其他情况下使用它是否合适.
具体来说,如果一个类NSCoding通过编码/解码其实例变量来符合,而不是整个实例,那么它仍然是可行的NSSecureCoding吗?
假设我有一个实现NSCoding如下的类
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:self.aString forKey:@"aMeaningfulString"];
}
- (id)initWithCoder:(NSCoder *)decoder {
if((self = [super init])) {
self.aString = [decoder decodeObjectForKey:@"aMeaningfulString"];
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
并且还假设没有涉及XPC.此类的实例将存储在磁盘上的plist中.
在安全方面,使用是否有任何好处,-decodeObjectOfClass:forKey:而不是
-decodeObjectForKey:?
我一直在寻找一篇文章,解释NSCoding(NSKeyedArchiver ...)使用CoreData(SQLite ....)的优缺点.
有很多的选择,我可以实现自己的自定义二进制读/写器,或使用的Plist/XML/JSON ...或使用SQLite或NSCoding.
我现在有点迷失了.任何机构都可以解释MAIN功能之间的区别吗?
我试图序列化SearchEntity对象(自定义对象)含有NSMutableDictionary含一组类型的CategoryEntity(自定义对象).
1 SearchEntity<NSCoding>包含:1 NSMutableDictionary(参数)参数,包含X CategoryEntities<NSCoding>只包含字符串和数字.
在这条线[encoder encodeObject:parameters forKey:kPreviousSearchEntityKey];的SearchEntity encodeWithCoder"我得到GDB:中断每一次,没有错误消息,异常等只是GDB:中断.
这是SearchEntity和参数的实现NSMutableDictionary
#pragma mark -
#pragma mark NSCoding delegate methods
- (void) encodeWithCoder:(NSCoder*)encoder
{
//encode all the values so they can be persisted in NSUserdefaults
if (parameters)
[encoder encodeObject:parameters forKey:kPreviousSearchEntityKey]; //GDB:Interrupted!
}
- (id) initWithCoder:(NSCoder*)decoder
{
if (self = [super init])
{
//decode all values to return an object from NSUserdefaults in the same state as when saved …Run Code Online (Sandbox Code Playgroud) nscoding ×10
ios ×9
swift ×5
objective-c ×2
swift3 ×2
xcode ×2
cocoa-touch ×1
core-data ×1
persistence ×1
security ×1
sigabrt ×1
wkwebview ×1
xcode6 ×1