如何在 osx 中归档一个普通的蓝色立方体对象?

How do you archive a plain blue cube object in osx?

我在 IB 中有一个名为 AppController 的普通蓝色立方体对象。这是头文件:

//AppController.h
#import <Cocoa/Cocoa.h>

@interface AppController : NSObject <NSCoding>

@property (weak) IBOutlet NSView *view;
@property (assign) int numberOfPresses;

- (IBAction)buttonPressed:(id)sender;

@end

如您所见,它有一个视图出口,一个名为 numberOfPresses 的 属性,以及与 IB 中的按钮相关联的操作。

这里是实现文件

//AppController.m
#import "AppController.h"

@implementation AppController

-(void)awakeFromNib {
    NSLog(@" number of presses = %d", _numberOfPresses);
}

- (IBAction)buttonPressed:(id)sender {
    _numberOfPresses++;
    NSLog(@" number of presses = %d", _numberOfPresses);
}


#pragma mark - Coding Protocol

-(void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeInt:_numberOfPresses forKey:@"numberOfPresses"];
}

-(id)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    if (self) {
        _numberOfPresses = [aDecoder decodeIntForKey:@"numberOfPresses"];
    }
    return self;
}

@end

如您所见,当用户按下按钮时,numberOfPresses 会增加。当我退出应用程序并再次启动它时,我想要

  1. 要记住的次数。
  2. 视图出口仍指向有效视图。

现在我的 numberOfPresses 始终为 0,如果我尝试使用 AppDelegate 中的 NSKeyedArchiver 和 NSKeyedUnarchiver 强制归档,那么我最终会得到 view = null。

这个问题是从 IB 归档纯蓝色立方体对象的一般问题。但是我在网上没有找到关于这个的解释,虽然这应该是一个很普遍的问题。我一定是遗漏或误解了什么。

要求 #2 应该很简单。如果您什么都不做,那么应该加载 AppController 及其创建的视图。从某种意义上说,它 "pre-archived" 适合你。

也就是说真正的问题是如何恢复按下的次数。 对于这么简单的事情,NSUserDefaults 是一个可能的候选者。更新印刷机上的默认值并在 awakeFromNib.

期间检索它

自定义存档和取消存档通常更适合动态创建的完整自定义对象,而不是从 IB 加载的对象。

(如果您需要恢复的是一个复杂的对象网络,我会改为谈论 CoreData。)

我想要的是一个通用的解决方案,我可以在任何项目中实施,并且只使用 NSCoding。 (如果有人有更简单的解决方案,我非常想听听)。通过引入两个对象:一个 Hub 和一个 RootObject,我最终得到了一个可行的解决方案。思路可以概括为三点:

  1. 我们的想法是让您想要存档的所有对象都不再出现在 IB 中。

  2. 引入一个负责所有IB连接的Hub对象。 Hub 是 IB 中的一个蓝色立方体,有一个 AppDelegate 的出口。 AppDelegate 有一个到 Hub 的出口。

  3. 引入一个 RootObject,其目的是将归档传播到要归档的所有对象。 RootObject 由 AppDelegate 拥有。 AppDelegate 负责启动归档和解档,RootObject 是中介。