我有一个必须符合的对象,NSCoding它包含一个UInt64值数组.我怎么能用它来编码/解码呢NSCoder?奖金问题:我怎样才能最紧凑地编码?(它必须进入已保存的Game Center状态数据,其大小有限.)
理想情况下,我只想写一个数组Int的大小n,然后写入n64位的a UInt64,并以类似方式读取它.我可以这样做吗?
coder.encodeObject(values, forKey: "v") 不起作用.
class MyObject: NSCoding {
private var values: [UInt64]
// …
// MARK: - NSCoding
required init(coder decoder: NSCoder) {
// ???
}
func encodeWithCoder(coder: NSCoder) {
// ???
}
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用NSCoding协议来读取和写入数据到plist.当我尝试编写[GolfHoles]时,我得到一个例外,它是NSObject的子类.我已经阅读了几个不同方法的帖子,但都没有帮助.
class GolfCourse: NSObject, NSCoding {
var name: String = ""
var location: String = ""
var holes: [GolfHole] = [GolfHole]()
init(holes: [GolfHole]) {
self.holes = holes
}
// MARK: NSCoding Protocol
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(name, forKey: "name")
aCoder.encodeObject(location, forKey: "location")
aCoder.encodeObject(holes, forKey: "holes") // exception here
}
required init(coder aDecoder: NSCoder) {
super.init()
name = aDecoder.decodeObjectForKey("name") as! String
location = aDecoder.decodeObjectForKey("location") as! String
holes = aDecoder.decodeObjectForKey("holes") as! [GolfHole]
}
override init() {
super.init()
for var i=0; i<18; i++ …Run Code Online (Sandbox Code Playgroud) 我一直试图找出如何使用带有NSCoding的Enum类型保存字典数组.
我有一个奖章类型的枚举
enum Medal: String {
case Unearned = "NoMedal"
case Gold = "GoldMedal"
case Silver = "SilverMedal"
}
Run Code Online (Sandbox Code Playgroud)
我的GameData.swift类中有一系列带有奖章类型的词典.
var medals: [[String: Medal]] = [
["1": .Unearned, "2": .Unearned, "3": .Unearned]
...
]
Run Code Online (Sandbox Code Playgroud)
比我在解码器方法中有这个代码
convenience required init?(coder decoder: NSCoder) {
self.init()
medals = decoder.decodeObjectForKey(Key.medals) as? [[String: Medal]] ?? medals
}
Run Code Online (Sandbox Code Playgroud)
这是编码器方法,我认为这是导致我的问题
// MARK: - Encode
func encodeWithCoder(encoder: NSCoder) {
encoder.encodeObject(medals as? AnyObject, forKey: Key.medals)
}
Run Code Online (Sandbox Code Playgroud)
问题是重新启动它没有保存/加载奖牌阵列,它会一直重置为默认值.
我也尝试过这个
encoder.encodeObject(medals as? [[String: Medal]], forKey: Key.medals)
Run Code Online (Sandbox Code Playgroud)
它会导致编译器错误.
我也不能使用常规语法
encoder.encodeObject(medals, forKey: Key.medals)
Run Code Online (Sandbox Code Playgroud)
就像我对使用正常值的字典数组(例如[String:Int])一样,因为编译器也会抛出错误
我试图使我的类符合NSCoding,但遇到问题,因为它的一个属性是枚举,如下所示:
enum Direction {
case north
case south
}
Run Code Online (Sandbox Code Playgroud)
如果枚举是可编码的,我可以这样做:
class MyClass: NSObject, NSCoding {
var direction: Direction!
required init(coder aDecoder: NSCoder) {
direction = aDecoder.decodeObject(forKey: "direction") as! Direction
}
func encode(with aCoder: NSCoder) {
aCoder.encode(direction, forKey: "direction")
}
}
Run Code Online (Sandbox Code Playgroud)
但是枚举不可编码因此encode()会引发错误.
" 如何在swift中使用NSCoder编码枚举? " 的答案建议编码枚举rawValue,然后从rawValue另一端初始化它.但在这种情况下,Direction没有了rawValue!
它确实有一个hashValue,看起来很有希望.我可以hashValue毫无问题地编码它,并Int在另一端解码回来.但似乎没有办法从它初始化枚举hashValue,所以我不能把它变成一个Direction.
如何编码和解码无值枚举?
在MyClass进入框架之前,我可以将实例保存MyClass到Core Data中.
这是实施MyClass:
open class MyClass: NSObject, NSCoding {
required public init?(coder aDecoder: NSCoder) {
super.init()
stuffs = aDecoder.decodeObject(forKey: "stuff") as? [Stuff] ?? []
}
open func encode(with aCoder: NSCoder) {
aCoder.encode(stuffs, forKey: "stuffs")
}
}
Run Code Online (Sandbox Code Playgroud)
在MyClass使用CocoaPods进入框架后,我开始遇到这些崩溃:
CoreData: error: exception handling request: <NSSQLFetchRequestContext: 0x1c019d4d0> , *** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (MyClass) for key (NS.objects); the class may be defined in source code or a library that is not linked …Run Code Online (Sandbox Code Playgroud) 我试图将我的对象图保存到一个文件,然后在以后重新加载它,但是decodeObjectForKey:对于我指定的任何键,总是返回nil.
创建了一个二进制文件,其中偶尔会有人类可读的文本,即titleTextColor,所以我认为归档过程正在运行.
我是否想念NSKeyedArchiver和NSKeyedUnarchiver是如何工作的?任何帮助,将不胜感激.
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeFloat:titleFontSize forKey:@"titleFontSize"];
[encoder encodeObject:[UIColor orangeColor] forKey:@"titleTextColor"];
[encoder encodeObject:lineSeparatorColor forKey:@"lineSeparatorColor"];
[encoder encodeObject:bodyTextColor forKey:@"bodyTextColor"];
[encoder encodeFloat:bodyTextFontSize forKey:@"bodyTextFontSize"];
[encoder encodeObject:backgroundColor forKey:@"backgroundColor"];
[encoder encodeObject:tintColor forKey:@"tintColor"];
[encoder encodeInteger:bodyTextAlignment forKey:@"bodyTextAlignment"];
[encoder encodeObject:@"Text" forKey:@"Text"];
}
+ (void) saveToFile {
// Get the shared instance
PSYDefaults *sharedInstance = [PSYDefaults sharedInstance];
// Serialise the object
NSData *serializedObject = [NSKeyedArchiver archivedDataWithRootObject:sharedInstance];
// Get the path and filename of the file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString …Run Code Online (Sandbox Code Playgroud) 当我尝试使用NSMutableArray对自定义对象进行编码时,我总是会遇到以下异常:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'cannot encode (void *) value: <2063e916>'
Run Code Online (Sandbox Code Playgroud)
什么可能导致这个?mutablearray被初始化,并且在它断开的那一点上有数据.我很确定我在'encodeWithCoder'方法中做错了,因为如果我把它保持为空,它运行良好.
这就是我尝试将我的mutablearray转换为数组的方法,但这没有帮助:
- (void) encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:[[NSArray alloc] initWithArray:_myMutableArray] forKey:kMutableArrayKey];
}
Run Code Online (Sandbox Code Playgroud) So my table view is not loading anything and I think it's because of this warning that I get. It saids the save function is not being used so how can it load something that is not saved. What I am saving is the indexPath and Section of the row that the user selected via a button action in the row.
Warning:
Result of call to 'save(defaults:)' is unused
Code:
func saveSorting(_ dataIdBlock: (Any) -> String) {
guard let items …Run Code Online (Sandbox Code Playgroud) 如何使用 NSCoding 保存我的结构,以便即使用户关闭应用程序它也不会改变?如果您还可以向我展示如何正确实现缺失的代码,我将不胜感激。
使用以下两个新函数更新:这是我的代码:
struct RandomItems: Codable
{
var items : [String]
var seen = 0
init(items:[String], seen: Int)
{
self.items = items
self.seen = seen
}
init(_ items:[String])
{ self.init(items: items, seen: 0) }
mutating func next() -> String
{
let index = Int(arc4random_uniform(UInt32(items.count - seen)))
let item = items.remove(at:index)
items.append(item)
seen = (seen + 1) % items.count
return item
}
func toPropertyList() -> [String: Any] {
return [
"items": items,
"seen": seen
]
}
}
override func viewWillDisappear(_ …Run Code Online (Sandbox Code Playgroud)