我已经实现了保存applicationWillTerminate和加载applicationWillFinishLoading。有一个完整的对象树,所有对象树都实现了NSCoding协议,并且我已经检查了我输入的类型。
其中一个类还存储NSMutableData了NSKeyedArchive,我怀疑这有时可能会破坏解档。奇怪的是,有时有效,有时无效。我怀疑其中的某些内容NSMutableData会破坏存档。
我对所有对象使用encodeObject,除了 bools 和 int,我在其中使用正确的相应方法 (encodeBool:forKey:和encodeInt:forKey:)
更清楚地说:代码确实有效,有时它能够重建一个相当完整的对象图,但并非总是如此。
我收到的错误消息是:
initForReadingWithData incomprehensible archive 0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30
Run Code Online (Sandbox Code Playgroud)
添加:失败的代码,大小超过NSMutableData10 MB
- (void)encodeWithCoder:(NSCoder*)encoder {
[encoder encodeObject:self.encodedMessage forKey:@"EncodedMessage"]; //NSData
[encoder encodeObject:self.data forKey:@"Data"]; //NSMutableData (10+MB)
[encoder encodeObject:self.header forKey:@"Header"]; //NSString
[encoder encodeObject:self.fileName forKey:@"FileName"]; //NSString
[encoder encodeInt:self.dataStartIndex forKey:@"DataStartIndex"]; //int
[encoder encodeInt:self.dataEndIndex forKey:@"DataEndIndex"]; //int
}
- (id)initWithCoder:(NSCoder*)decoder {
if (self = [super init]) {
self.encodedMessage = …Run Code Online (Sandbox Code Playgroud) 我阻止某事,我确信它太大了.我有一个看起来像这样的自定义对象
@interface DownloadObject : NSObject <NSCoding>{
NSNumber *key;
NSString *name;
NSNumber *progress;
NSNumber *progressBytes;
NSNumber *size;
NSString *path;
}
@property (copy) NSNumber *key;
@property (copy) NSString *name;
@property (copy) NSNumber *progress;
@property (copy) NSNumber *size;
@property (copy) NSString *path;
@property (copy) NSNumber *progressBytes;
-(id)initWithKey:(NSNumber *)k name:(NSString *)n progress:(NSNumber *)pro size:(NSNumber *)s path:(NSString *)p progressBytes:(NSNumber *)pb;
@end
Run Code Online (Sandbox Code Playgroud)
并实施
@implementation DownloadObject
@synthesize size, progress, name, key, path, progressBytes;
-(id)initWithKey:(NSNumber *)k name:(NSString *)n progress:(NSNumber *)pro size:(NSNumber *)s path:(NSString *)p progressBytes:(NSNumber *)pb
{
self.key …Run Code Online (Sandbox Code Playgroud) 我正在为 iPhone 应用程序编写一些代码,但在正确加载默认数据时遇到问题。我的代码基于 Ray Wenderlich 所著的“学习 Cocos2d”书中的一些示例。
看来,即使我完全删除应用程序并尝试从新数据开始,应用程序也会不一致地不尝试加载数据,或者错误地认为存在数据并加载空值。
我使用 containsValueForKey 检查某个值是否存在,然后加载它或加载一些默认值,但即使在全新安装上, containsValueForKey 也会找到数据并且不会加载默认值。在 xcode 的管理器中,我检查了设备的文件结构和我指定保存的文档文件夹,看起来它不包含任何文件,所以我不确定它正在抓取什么。
我的猜测是问题与 initWithCoder 函数有关。有时它似乎神秘地经历了这个功能,但并非总是如此。另一个奇怪的事情是,[[GameManager sharedGameManager] save]当玩家获得高分时我调用(此处未显示,但代码与此 ObjectiveList 完全相同,只有一个 int)并且它似乎正确保存了它。
现在是代码:
GC数据库.h
#import <Foundation/Foundation.h>
id loadData(NSString * filename);
void saveData(id theData, NSString *filename);
Run Code Online (Sandbox Code Playgroud)
GC数据库.m
#import "GCDatabase.h"
NSString * pathForFile(NSString *filename) {
// 1
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
// 2
NSString *documentsDirectory = [paths objectAtIndex:0];
// 3
return [documentsDirectory stringByAppendingPathComponent:filename];
}
id loadData(NSString * filename) {
NSString *filePath = pathForFile(filename);
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSData …Run Code Online (Sandbox Code Playgroud) 我有一个使用NSKeyedArchiver. 有没有办法遍历其中的所有值?必须能够以某种方式获取使用+[NSKeyedUnarchiver unarchiveObjectWithData:].
谢谢
我是 iOS 编程的新手,我刚刚学习了一些关于保存/加载对象的基础知识。在我的书中,有一个将图像保存到文件的示例:
NSData *data = UIImageJPEGRepresentation(someImage, 0.5);
[data writeToFile:imagePath atomically:YES];
Run Code Online (Sandbox Code Playgroud)
我的书还有一个将“essay”对象保存到文件的示例(“essay”对象有一个字符串作为标题,另一个字符串用于作者):
essay.m符合<NSCoding>协议:
- (void) encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.essayTitle forKey:@"essayTitle"];
[aCoder encodeObject:self.essayAuthor forKey:@"essayAuthor"];
}
- (instancetype) initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
_essayTitle = [aDecoder decodeObjectForKey:@"essayTitle"];
_essayAuthor = [aDecoder decodeObjectForKey:@"essayAuthor"];
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
在essayStore.m:
[NSKeyedArchiver archiveRootObject:self.myEssay toFile:somePath];
Run Code Online (Sandbox Code Playgroud)
我有三个问题:
什么时候应该使用 NSData 将对象保存到一个/多个文件,什么时候我应该遵守<NSCoding>协议将对象保存到一个/多个文件?
什么时候应该将所有对象保存到一个文件中,什么时候应该为每个对象保存一个文件?
如果我的论文对象中有图像,我如何将其与图像一起保存?
谢谢!
这是我的第一篇论文帖子,所以在审核我的帖子技巧时请建设性的!
基本上,我的问题是我有一系列自定义对象,我需要与今天的扩展共享.对象表示待办事项列表中的任务,其属性用于存储有关每个任务的信息(名称,位置,dueDate,缩略图等).对象存储在一个数组中,该数组用于填充我的待办事项列表.我想做的就是将这个数组传递给我的小部件,这样我就可以填充第二个tableview,它将作为第一个的压缩版本(对于widget视图).
我应该指出我的小部件已正确设置,因为我已将它与包含的应用程序正确地链接在"组"中.我还成功地使用NSUserDefaults将NSStrings数组传递给窗口小部件,但是,当我尝试将对象数组传递给窗口小部件时,它崩溃了,我的日志显示为:
*** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (Xitem)'
Run Code Online (Sandbox Code Playgroud)
我知道这次崩溃与归档对象(Xitem)有关,这似乎是在NSUserDefaults中保存自定义对象的必要步骤.但是,我已经测试了在包含应用程序的同一类中保存/加载数组,并且工作正常!(以下代码)
NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:self.Xitems];
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.AaronTest"];
[defaults setObject:encodedObject forKey:@"myArray"];
[defaults synchronize];
NSUserDefaults *defaults2 = [[NSUserDefaults alloc] initWithSuiteName:@"group.AaronTest"];
NSData *encodedObject2 = [defaults2 objectForKey:@"myArray"];
NSArray *array2 = [NSKeyedUnarchiver unarchiveObjectWithData:encodedObject2];
for (Xitem *t in array2){
NSLog(@"*****%@*****", t.itemName);
}
Run Code Online (Sandbox Code Playgroud)
好的,正如所解释的,上面的代码按预期工作.但是,当我将此代码的第二个"unarchiver"插入我今天的小部件时,我得到上述错误.下面是我的代码,以显示我如何编码/解码对象(可能值得注意的是,这个对象是为了简化我的调试而创建的,只包含一个NSString属性):
Xitem.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
@interface Xitem : NSObject <NSCoding>
{
NSString *itemName;
}
-(void)encodeWithCoder:(NSCoder*)encoder;
-(id)initWithCoder:(NSCoder*)decoder;
@property …Run Code Online (Sandbox Code Playgroud) 我正在尝试制作通用的NSCoding实现,并且由于更新版本的应用程序,当对象的类型在平均时间内发生变化时会出现解码问题.
我从Swift调用validateValue方法时遇到问题.功能签名是:
func validateValue(_ ioValue: AutoreleasingUnsafeMutablePointer<AnyObject?>, forKey key: String, error outError: NSErrorPointer) -> Bool
Run Code Online (Sandbox Code Playgroud)
作为参考,Apple文档可以在这里找到:NSCoding validateValue
我想要创建的代码是:
public class func decodeObjectWithCoder(theObject:NSObject, aDecoder: NSCoder) {
for (key, value) in toDictionary(theObject) {
if aDecoder.containsValueForKey(key) {
let newValue: AnyObject? = aDecoder.decodeObjectForKey(key)
NSLog("set key \(key) with value \(newValue)")
var error:NSError?
var y:Bool = theObject.validateValue(newValue, forKey: key, error: &error)
if y {
theObject.setValue(newValue, forKey: key)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我无法正确调用.validateValue.我不断收到编译错误.我该怎么称呼它.toDictionary函数可以在以下位置找到:EVReflection
更新:我刚刚发现这段代码编译:
var ioValue: AutoreleasingUnsafeMutablePointer<AnyObject?> = nil
var y:Bool = theObject.validateValue(ioValue, forKey: key, …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建我的第一个sprite kit swift游戏,并且我的游戏数据使用nsuserdefaults.我想让它更安全,所以我试图过渡到NSCoding,但我在网上找到的任何东西都没有完全帮助我,只是让我感到困惑(很抱歉,如果答案已经存在,我可能已经看过它并且没有能够理解.)
这是我的GameState类:
class GameState {
var score: Int
var highScore: Int
var stars: Int
var sound: Bool
var carType: Int
var xSize: Double
var ySize: Double
var gameOver: Bool
class var sharedInstance: GameState {
struct Singleton {
static let instance = GameState()
}
return Singleton.instance
}
init() {
// Init
score = 0
highScore = 0
stars = 0
carType = 1
sound = true
xSize = 1
ySize = 1
gameOver = false
// Load game state …Run Code Online (Sandbox Code Playgroud) 我正在使用 Swift 进行开发。我想通过存储自定义数据nsuserdefaults。
我的自定义数据如下
在ConnectedDevice.swift中
import UIKit
import Foundation
import CoreBluetooth
import CoreLocation
class ConnectedDevice : NSObject , NSCoding{
var RSSI_threshold:NSNumber=0
var Current_RSSI:NSNumber=0
var name:String?
var bdAddr:NSUUID?
var ConnectState:Bool=false
var AlertState:Int=0
var BLEPeripheral : CBPeripheral!
var DisconnectAddress:[String] = [String]()
var DisconnectTime:[String] = [String]()
var Battery:NSInteger=0
var Location:[CLLocation] = [CLLocation]()
var AlertStatus:Int!
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(RSSI_threshold, forKey: "RSSI_threshold")
aCoder.encodeObject(Current_RSSI, forKey: "Current_RSSI")
aCoder.encodeObject(name, forKey: "name")
aCoder.encodeObject(bdAddr, forKey: "bdAddr")
aCoder.encodeBool(ConnectState, forKey: "ConnectState")
aCoder.encodeInteger(AlertState, forKey: "AlertState")
aCoder.encodeObject(BLEPeripheral, forKey: "BLEPeripheral")
aCoder.encodeObject(DisconnectAddress, …Run Code Online (Sandbox Code Playgroud) 在测试新的 Codable 如何与 NSCoding 交互时,我使用包含 Codable 结构的 Class 进行了涉及 NSCoding 的操场测试。丝毫
struct Unward: Codable {
var id: Int
var job: String
}
class Akward: NSObject, NSCoding {
var name: String
var more: Unward
init(name: String, more: Unward) {
self.name = name
self.more = more
}
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
aCoder.encode(more, forKey: "more")
}
required init?(coder aDecoder: NSCoder) {
name = aDecoder.decodeObject(forKey: "name") as? String ?? ""
more = aDecoder.decodeObject(forKey: "more") as? Unward ?? Unward(id: -1, job: …Run Code Online (Sandbox Code Playgroud) nscoding ×10
ios ×5
objective-c ×5
swift ×4
cocoa ×3
archiving ×1
codable ×1
foundation ×1
macos ×1
nsdata ×1
nsobject ×1
sprite-kit ×1
swift4 ×1
widget ×1
xcode ×1