标签: nscoding

存档/取消存档导致 initForReadingWithData 无法理解存档

我已经实现了保存applicationWillTerminate和加载applicationWillFinishLoading。有一个完整的对象树,所有对象树都实现了NSCoding协议,并且我已经检查了我输入的类型。

其中一个类还存储NSMutableDataNSKeyedArchive,我怀疑这有时可能会破坏解档。奇怪的是,有时有效,有时无效。我怀疑其中的某些内容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)

macos xcode objective-c archiving nscoding

5
推荐指数
2
解决办法
4986
查看次数

在Cocoa中将自定义对象写入.plist

我阻止某事,我确信它太大了.我有一个看起来像这样的自定义对象

 @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)

cocoa objective-c nscoding nsobject

5
推荐指数
2
解决办法
1万
查看次数

NSCoding 和保存/加载默认值问题

我正在为 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)

nscoding cocos2d-iphone ios initwithcoder

5
推荐指数
1
解决办法
1582
查看次数

如何查找 NSKeyedArchiver/NSKeyedUnarchiver 中使用的所有密钥

我有一个使用NSKeyedArchiver. 有没有办法遍历其中的所有值?必须能够以某种方式获取使用+[NSKeyedUnarchiver unarchiveObjectWithData:].

谢谢

cocoa objective-c nscoding foundation

5
推荐指数
1
解决办法
1416
查看次数

NSCoding 和 NSData 是什么关系?

我是 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)

我有三个问题:

  1. 什么时候应该使用 NSData 将对象保存到一个/多个文件,什么时候我应该遵守<NSCoding>协议将对象保存到一个/多个文件?

  2. 什么时候应该将所有对象保存到一个文件中,什么时候应该为每个对象保存一个文件?

  3. 如果我的论文对象中有图像,我如何将其与图像一起保存?

谢谢!

cocoa objective-c nscoding nsdata ios

5
推荐指数
1
解决办法
6493
查看次数

使用NSUserDefaults与Today Extension(小部件)共享一组自定义对象

这是我的第一篇论文帖子,所以在审核我的帖子技巧时请建设性的!

基本上,我的问题是我有一系列自定义对象,我需要与今天的扩展共享.对象表示待办事项列表中的任务,其属性用于存储有关每个任务的信息(名称,位置,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)

widget objective-c nsuserdefaults nscoding ios

5
推荐指数
1
解决办法
910
查看次数

如何调用validateValue方法

我正在尝试制作通用的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)

nscoding swift

5
推荐指数
1
解决办法
1293
查看次数

从NSUserDefaults更改为NSCoding

我正在尝试创建我的第一个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)

nsuserdefaults nscoding ios sprite-kit swift

5
推荐指数
1
解决办法
156
查看次数

如何在 swift 中通过 nsuserdefaults 存储像 CBPeripheral 这样的自定义数据?

我正在使用 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)

nsuserdefaults nscoding ios swift

5
推荐指数
1
解决办法
3394
查看次数

NSCoding 和 Codable 可以共存吗?

在测试新的 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 swift swift4 codable

5
推荐指数
2
解决办法
3372
查看次数