背景
我正在尝试使用NSCoding协议对String样式的枚举进行编码,但是我遇到了从String转换回来的错误.
解码和编码时出现以下错误:
字符串不可转换为Stage
额外参数ForKey:在电话中
码
enum Stage : String
{
case DisplayAll = "Display All"
case HideQuarter = "Hide Quarter"
case HideHalf = "Hide Half"
case HideTwoThirds = "Hide Two Thirds"
case HideAll = "Hide All"
}
class AppState : NSCoding, NSObject
{
var idx = 0
var stage = Stage.DisplayAll
override init() {}
required init(coder aDecoder: NSCoder) {
self.idx = aDecoder.decodeIntegerForKey( "idx" )
self.stage = aDecoder.decodeObjectForKey( "stage" ) as String // ERROR
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeInteger( …
Run Code Online (Sandbox Code Playgroud) 我的类有以下方法,它打算加载一个nib文件并实例化该对象:
- (id)initWithCoder:(NSCoder*)aDecoder
{
if(self = [super initWithCoder:aDecoder]) {
// Do something
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
如何实例化这个类的对象?这是什么NSCoder
?我该如何创建它?
MyClass *class = [[MyClass alloc] initWithCoder:aCoder];
Run Code Online (Sandbox Code Playgroud) 我想用这些步骤做点什么:
所以我想从N获得所有的键和值.我怎么能这样做?
我不太了解NSKeyedUnarchiver,请帮助我.
尝试使用NSCoder时出错
Player.swift:
class Player: NSObject, NSCoding {
private var _playerName: String!
private var _playerScore: Int!
private var _playerColor: PlayerColor! //PlayerColor is an enum
var playerName: String {
get {
return _playerName
}
set {
_playerName = newValue
}
}
var playerScore: Int {
get {
return _playerScore
}
set {
_playerScore = newValue
}
}
var playerColor: PlayerColor {
get {
return _playerColor
}
set {
_playerColor = newValue
}
}
init(playerName: String, playerScore: Int, playerColor: PlayerColor) {
_playerName = …
Run Code Online (Sandbox Code Playgroud) 我正在使用encodeRestorableState
/ restoreStateWithCoder
来保存和恢复窗口的状态.(我正在手动执行此操作,因为我希望在文档中显式保存窗口状态,而不仅仅依赖于恢复其状态作为恢复应用程序状态的一部分的操作系统)
我遇到的问题是,当它恢复时,控制台中会记录一个错误,它无法恢复第一个响应者,因为有问题的视图将其窗口设置为nil.
我尝试makeFirstResponder(nil)
在编码之前调用,但随后窗口是它自己的第一个响应器,并抛出异常,因为它无法编码自身.
我是从我的窗口控制器那里做的windowDidLoad
.这样做awakeFromNib
并没有什么不同.
那么有没有办法可以阻止窗口保存/恢复第一个响应者,或者确保第一个响应者视图首先安装在窗口中?
在使用Apple LLVM编译器3.0并使用-O3编译时,我发现了一个与NSCoder不同的错误.它只会在设备上崩溃.我测试了运行iOS 5的iPhone 4,运行iOS 5的iPad 2和运行iOS 4的iPad 1.所有都崩溃了.这是相关的代码部分:
-(id)initWithCoder:(NSCoder*)decoder
{
if (![super init])
{
return nil;
}
NSUInteger length = 0;
uint8_t* data = (uint8_t*)[decoder decodeBytesForKey:BBKey returnedLength:&length];
m_value = *(BBPointI32*)data;
return self;
}
Run Code Online (Sandbox Code Playgroud)
这就是BBPointI32:
typedef struct
{
NSInteger x;
NSInteger y;
}
BBPointI32;
Run Code Online (Sandbox Code Playgroud)
取消引用EXC_BAD_ACCESS
时会发生这种情况data
.这不是空指针问题.如果我附加GDB,我可以看到长度是8,sizeof(BBPointI)也是8,数据是正确的.
如果我查看反汇编,崩溃就发生在:
ldrd r2, r3, [r0]
Run Code Online (Sandbox Code Playgroud)
看起来不错.r0包含0xb546e,这是地址data
.当我检查那个内存时,我可以看到它包含我期望的数据.对于任何感兴趣的人,r2包含72(不确定是什么),r3包含8(最可能是值length
).
任何人都可以对这个问题有所了解吗?
在我的应用程序中,我定期将一组动态数据写入文件.数据对象每秒都会更新一次.偶尔我会在我的encodeWithCoder:方法中的一行上得到"Collection is mutated in mutated"异常.每个对象的编码如下:
[aCoder encodeObject:self.speeds forKey:@"speeds"];
Run Code Online (Sandbox Code Playgroud)
self.speeds是一个NSMutableArray.我假设问题是数据在编码时正在更新.我尝试在编码和保存块中使用@synchronize,我也尝试将属性设置为原子而不是非原子,但都没有工作.节约是发生在后台.有关如何在更新时在后台保存此数据的任何想法?我想制作副本然后保存副本会起作用,但不会出现同样的问题吗?谢谢!
应用程序中的想法是我打开一个地图视图,它定期更新包含数据对象数组的单例类,每个数据对象都是用户的地图信息.在每个数据对象,用户的位置,速度,高度,距离等每三次外景经理更新用户的位置,我更新当前数据对象(这是刚刚创建跟踪此脱扣的"活动"的数据对象使用新信息只能有一个"实时"数据对象.
我想每隔x分钟将整个单例写入一个文件,但有时写入和更新同时发生,我得到这个错误(或者至少这是我认为导致这种崩溃的原因).这是我的代码或我的设计模式的问题吗?
这是我的自定义类中的编码方法:
- (void)encodeWithCoder:(NSCoder*)aCoder {
@synchronized([SingletonDataController sharedSingleton]) {
[aCoder encodeObject:[[lineLats copy] autorelease] forKey:@"lineLats"];
[aCoder encodeObject:[[lineLongs copy] autorelease] forKey:@"lineLongs"];
[aCoder encodeObject:[[horizontalAccuracies copy] autorelease] forKey:@"horAcc"];
[aCoder encodeObject:[[verticalAccuracies copy] autorelease] forKey:@"vertAcc"];
[aCoder encodeObject:[[speeds copy] autorelease] forKey:@"speeds"];
[aCoder encodeObject:[[overlayColors copy] autorelease] forKey:@"colors"];
[aCoder encodeObject:[[annotationLats copy] autorelease] forKey:@"annLats"];
[aCoder encodeObject:[[annotationLongs copy] autorelease] forKey:@"annLongs"];
[aCoder encodeObject:[[locationManagerStartDate copy] autorelease] forKey:@"startDate"];
[aCoder encodeObject:[[locationManagerStartDateString copy] autorelease] forKey:@"locStartDateString"];
[aCoder encodeObject:[[mapTitleString copy] autorelease] forKey:@"title"]; …
Run Code Online (Sandbox Code Playgroud) 如何在iOS 中使用NSCoder 解码long long类型属性initWithCoder:
并进行编码encodeWithCoder:
?
谢谢.
所以我正在阅读本教程,最后我想出了如何使用NSCoding归档对象,以及使用可用的初始化器再次从文件系统初始化它.
// To encode the object in the first place
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
}
// To 're-initialize' the object
required init?(coder aDecoder: NSCoder) {
self.name = aDecoder.decodeObject(forKey: "name") as! String
super.init()
}
Run Code Online (Sandbox Code Playgroud)
但是,我仍然有点不确定整个过程如何在高水平上运作.请告诉我我的想法不正确.
1)如果你的对象采用NSCoding协议,你可以使用encode(with :)函数让NSCoder对象通过函数传递并执行'encode'方法,传递你的对象的实例属性(它本身就是一个对象) )作为第一个参数,以及表示键作为第二个值的字符串.
2)这是一个递归过程,基本上,你传递对象的实例属性(即名称)的原因是为了使THAT属性(它是一个对象)可以发送编码消息,依此类推,依此类推直到它不再到达NSCoding采用者.
3)aDecoder对象也可以对事物进行解码,因此在初始化自定义对象时,您将需要使用可用的初始化程序来解码为您使用的模糊字符串键设置的任何对象.
这是我真的不明白的......
aDecoder对象如何知道哪个单独的对象用于该组键?例如,假设我有10个狗对象实例.当系统通过一个解码器,并在其上使用decodeObject方法,并且它通过键将self.name设置为该解码对象的值时,aDecoder如何知道该狗的名称被保存为"杰克",而不是偶然抓住其中一个狗实例的名字,比如"Jodi"?
换句话说,一旦你对对象的属性进行编码,文件系统如何知道将对象实例A的属性与对象实例B的属性分开,这样,当应用程序被引导备份并且对象A被初始化时,它只是抓住对象A的属性?
谢谢
我从XCode获取这些崩溃报告(我在底部粘贴了一个),我无法重现错误或弄清楚问题是什么.
从回溯中我认为它可能与这些decodeObject
东西有关......我确实遇到了新的decodeBool
和decodeDouble
函数的问题,所以为了确保我做了一个NSCoder扩展:
func safeDecodeDouble(key: String) -> Double? {
if self.containsValue(forKey: key) {
if let value = self.decodeObject(forKey: key) as? Double {
return value
}
return self.decodeDouble(forKey: key)
}
return nil
}
func safeDecodeBool(key: String) -> Bool? {
if self.containsValue(forKey: key) {
if let value = self.decodeObject(forKey: key) as? Bool {
return value
}
return self.decodeBool(forKey: key)
}
return nil
}
func safeDecodeDate(key: String) -> Date? {
if self.containsValue(forKey: key) {
if let value = …
Run Code Online (Sandbox Code Playgroud) nscoder ×10
ios ×4
swift ×4
objective-c ×3
arm ×1
asynchronous ×1
cocoa ×1
cocoa-touch ×1
enums ×1
iphone ×1
key ×1
llvm ×1
macos ×1
nscoding ×1
nswindow ×1
persistence ×1
swift3 ×1
xcode ×1