首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSKeyedArchiver保存iOS

NSKeyedArchiver保存iOS
EN

Stack Overflow用户
提问于 2014-04-27 18:11:51
回答 2查看 1.1K关注 0票数 0

我第一次想存钱。完成了我的应用程序,现在开始保存数据并在启动和关闭时加载。查看NSKeyedArchiver并将NSCoding中的两个方法添加到我的所有自定义类中:

代码语言:javascript
复制
-(void)encodeWithCoder:(NSCoder *)aCoder{
 // Encode Stuff
}

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

但是现在我发现了一个问题,我需要在哪里以及如何调用我的saveFile和loadFile?我的数据存储在FirstViewController中的两个数组中。我想用AppDelegate的- (void)applicationWillTerminate:(UIApplication *)application保存数据,用- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions加载数据,但是如何才能到达包含数组的FirstViewController类,以便从AppDelegate方法中存储?

这个想法是正确的,还是我需要用另一种方式去做呢?

亲切的问候

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-27 18:42:13

加载数据应该是“懒惰”的。这意味着数据应该在实际需要读取数据的第一分钟就被加载。此外,如果有大量的数据,你应该准备好在你的应用程序运行时释放它,以便其他应用可以使用RAM,这意味着你的应用程序更有可能在下次用户启动应用程序时仍在运行。

因此,创建一个提供对数据的访问的类,当任何东西第一次需要数据时,它会检查内部NSCoding对象是否是nil,如果是,那么就应该在那里加载数据。

至于保存,您应该在终止之前进行保存,但更重要的是,您还应该在用户修改的任何数据的一秒钟内保存。您的应用程序应该在任何时候崩溃,因为一个软件错误,或者它可能因为其他原因而终止,或者电池可能会简单地耗尽。

假设您的内部数据存储是使用NSMutableDictionary保存的NSKeyedArchiver。它具有一个具有键@"value"的值,其"getter“和"setter”实现如下:

代码语言:javascript
复制
- (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,您希望在那里保存到磁盘并释放内存,以便其他应用程序可以使用它:

代码语言:javascript
复制
- (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;
}
票数 2
EN

Stack Overflow用户

发布于 2014-04-27 18:16:23

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

这就是视图控制器代码通常是如何获得应用程序委托的,您可以在视图控制器中各自的-awakeFromNib方法中建立连接--这通常不那么棘手--让视图控制器与应用程序委托进行第一次接触,而不是让应用委托与视图控制器进行接触。

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

或者直接使用核心数据。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23327087

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档