NSKeyedArchiver保存iOS

时间:2014-04-27 18:11:51

标签: ios objective-c nscoding

我正试图第一次保存。制作我的应用程序,现在将在启动和关闭时保存数据和加载。查看NSKeyedArchiver并将NSCoding中的两个方法添加到我的所有自定义类中:

-(void)encodeWithCoder:(NSCoder *)aCoder{
 // Encode Stuff
}

-(id)initWithCoder:(NSCoder *)aDecoder{
    if (self = [super init])
        // Decode Stuff
    return self;
}

但是现在我发现了一个问题,我在哪里以及如何调用我的saveFile和loadFile?我的数据存储在FirstViewController的2个数组中。我想用AppDelegate的- (void)applicationWillTerminate:(UIApplication *)application保存数据并使用 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions加载数据但是如何通过其中的Arrays来从AppDelegate方法存储到FirstViewController类?

思维正确,还是我需要以其他方式进行?

亲切的问候

2 个答案:

答案 0 :(得分:2)

加载数据应该是"懒惰"。这意味着应该在您实际需要读取数据的第一个瞬间加载数据。此外,如果有大量数据,您应该准备在应用运行时释放它,以便其他应用可以使用RAM,这意味着您的应用更有可能在用户下次启动应用时仍在运行

因此,创建一个提供数据访问权限的类,并且第一次需要数据时它会检查内部NSCoding对象是否为nil,如果是,那么你应该在哪里加载数据。

至于保存,您应该在终止之前保存,但更重要的是,您还应该保存在用户修改的任何数据的大约一秒钟内。由于软件错误,您的应用程序随时会崩溃,或者由于其他原因可能会终止,或者电池可能会耗尽。

假设您的内部数据存储使用NSMutableDictionary保存NSKeyedArchiver。它的值为@"value",其中包含" getter"和" setter"这样实现:

- (NSString *)value
{
  if (!self.data)
    self.data = [NSKeyedUnarchiver unarchiveObjectWithFile:self.dataFile];

  return self.data[@"value"];
}

- (void)setValue:(NSString *)value
{
  if (!self.data)
    self.data = [NSKeyedUnarchiver unarchiveObjectWithFile:self.dataFile];

  self.data[@"value"] = value;
  self.needsSave = YES;

  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    [self save];
  });
}

- (void)save
{
  if (!self.needsSave)
    return;

  [NSKeyedArchiver archiveRootObject:self.data toFile:self.dataFile];
  self.needsSave = NO;
}

最后,您的班级还应注册UIApplicationDidReceiveMemoryWarningNotificationUIApplicationWillResignActiveNotificationUIApplicationWillTerminateNotification,您要将其保存到磁盘并释放RAM,以便其他应用可以使用它:

- (id)init
{
  if (!(self = [super init]))
    return nil;

  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveAndFreeMemory:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveAndFreeMemory:) name:UIApplicationWillResignActiveNotification object:nil];
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveAndFreeMemory:) name:UIApplicationWillTerminateNotification object:nil];

  return self;
}

- (void)saveAndFreeMemory:(NSNotification *)notif
{
  [self save];

  self.data = nil;
}

答案 1 :(得分:0)

UIApplication以正常方式启动时,您始终可以从应用中的任何对象调用[[UIApplication sharedApplication] delegate],这样您就可以获得对应用程序代理的引用。

这是视图控制器代码通常如何获得应用程序委托的方式,您在各自的-awakeFromNib方法中在视图控制器中建立连接 - 它通常不太容易出现视图控制器与app delegate进行第一次联系,而不是让app delegate与视图控制器联系。

让您的应用委托将已保存的数据解码为模型对象层次结构,让您的视图控制器与应用委托连接,并开始KV在-awakeFromNib中观察模型。

或者只使用核心数据。