【问题标题】:IOS: Save Array when app is close or enter backgroundIOS:当应用程序关闭或进入后台时保存数组
【发布时间】:2013-09-02 20:43:42
【问题描述】:

当应用程序处于后台模式或应用程序关闭时,我有一个 cartArray(在上面的 AppDelegate.h @interface 中)需要保存。当我在其中添加一个项目(购物车)并进入后台或通过按减号关闭应用程序时,cartArray 什么都没有但崩溃时,该应用程序运行良好。我的 cartArray 中包含购物车类。 我可以知道发生了什么吗?网上的教程太复杂了,我总是发现自己在解释中迷失了。

[AppDelegate.m]

- (void)applicationDidEnterBackground:(UIApplication *)application {
[AppDelegate saveData]; 
}

- (void)applicationWillEnterForeground:(UIApplication *)application {   
[AppDelegate getData];   
}

+(NSString *) getPathToAchieve{  NSLog(@"+++++getPathToAchieve");
    static NSString* docsDir = nil;
    if (docsDir == nil) {
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        docsDir = [paths objectAtIndex:0];
    }
    NSString *fullFileName = [NSString stringWithFormat:@"%@.plist", docsDir];
    return fullFileName;
}

- (void)applicationWillTerminate:(NSNotification *)notification{    
    [cartArray writeToFile:[AppDelegate getPathToAchieve] atomically:YES];
}

-(id)initWithCoder:(NSCoder *)aDecoder
{   self = [super init];
   if (self != nil)
   {
        cartArray = [aDecoder decodeObjectForKey:@"cartArrayKeys"];
   }
    return self;  
}

-(void)encodeWithCoder:(NSCoder *)anEncoder
{   
    [anEncoder encodeObject:cartArray forKey:@"cartArrayKeys"];
}

+(void)saveData{ 
     [NSKeyedArchiver archiveRootObject:cartArray toFile:[self getPathToAchieve] ];
}

+(id)getData{ 
    return [NSKeyedUnarchiver unarchiveObjectWithFile:[self getPathToAchieve]];
}

【问题讨论】:

  • 您能否将崩溃日志添加到您的问题中?
  • 看起来很糟糕的设计。在这种情况下,我建议您使用 CoreData。您不必担心数据是否已保存 - CoreData 会妥善处理。
  • CoreData中不需要,只有一个数组。首选NSDefaults

标签: iphone ios objective-c save


【解决方案1】:

您的代码非常混乱。首先,在Cart 类中实现-(id)initWithCoder:-(void)encodeWithCoder:,而不是AppDelegate 类(并确保Cart 符合NSCoding 协议):

- (void) encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:self.title forKey:@"title"];
    [encoder encodeObject:self.description forKey:@"description"];
    .....
}

- (id)initWithCoder:(NSCoder *)decoder {
    if (self = [super init]) {
        self.title = [decoder decodeObjectForKey:@"title"] ;
        self.description = [decoder decodeObjectForKey:@"description"] ;
        ....
    }
    return self;
}   

第二,实现-(void)saveData-(void)getData

-(void)saveData{ 
     [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:cartArray] forKey:@"cartArray"];
}

-(void)getData{ 
    NSData *savedArray = [[NSUserDefaults standardUserDefaults] objectForKey:@"cartArray"];
    if (savedArray != nil)
    {
        NSArray *oldArray = [NSKeyedUnarchiver unarchiveObjectWithData:savedArray];
        if (oldArray != nil) {
            cartArray = [[NSMutableArray alloc] initWithArray:oldArray];
        } else {
            cartArray = [[NSMutableArray alloc] init];
        }
    }
}

当应用程序将被终止/进入后台时,调用saveData。 应用程序加载完毕后调用getData

【讨论】:

  • 我将 saveData 和 loadData 放在哪里?也在购物车课上? @安德烈
  • 我得到声明的 currentDefaults for "NSData *savedArray = [currentDefaults objectForKey:@"cartArray"];"
  • 将 currentDefualts 替换为 [NSUserDefaults standardUserDefaults]。将您的数据保存在 applicationWillResignActive: 中,并将其加载到您的 AppDelegate 中的 applicationDidBecomeActive: 中。
  • 替换了currentDefaults,对不起,那是我的项目。请参阅编辑后的答案。 saveDataloadData 应该属于 AppDelegate 类,但我宁愿为此使用另一个类
【解决方案2】:

把所有的钱都存起来

- (void)applicationWillResignActive:(UIApplication *)application

来自文档:

告诉代理应用程序即将变为非活动状态。 调用此方法是为了让您的应用程序知道它即将 从活动状态变为非活动状态。这可能在某些情况下发生 临时中断类型(例如来电或 SMS 消息)或当用户退出应用程序并开始 过渡到后台状态。处于非活动状态的应用程序 state 继续运行,但不会将传入的事件分派到 响应者。您应该使用此方法暂停正在进行的任务,禁用 计时器,并降低 OpenGL ES 帧速率。游戏应该使用这个 暂停游戏的方法。处于非活动状态的应用程序应该 在等待过渡到活动或 背景状态。

【讨论】:

    【解决方案3】:

    如果你想永久保存一些数据,数组是一个临时存储,然后尝试使用 NSUSerDefult。关闭应用程序数组后可能会消失。 NSUSerDefult 数据不会消失。 NSUserDefault 仅在应用程序删除或从模拟器中删除应用程序时消失。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-14
      • 2013-11-04
      • 2013-07-03
      • 2022-12-01
      • 2016-07-17
      • 1970-01-01
      相关资源
      最近更新 更多