保存/加载IOS数据

Posted

技术标签:

【中文标题】保存/加载IOS数据【英文标题】:Save / Load IOS data 【发布时间】:2012-12-26 14:06:31 【问题描述】:

我一直在尝试让我的应用程序从应用程序中的一组数组中保存和加载数据,奇怪的问题是,当应用程序终止(完全关闭)时,重新启动时数据似乎没有加载,我看过很多帖子、教程等,但我似乎无法让它工作,我在应用程序上有两个测试按钮来触发保存和加载方法,还有一个按钮来清除记录,当我使用这些进行测试时,它可以完美运行并且数据可以正确保存和加载。

我目前的设置如下:

我在支持文件目录中有一个名为 data.plist 的 plist 文件,在该文件中,我有各种数组,索引 0 中的数据与全局数据类创建自身实例时初始化的数据相同。

我的存档代码:

- (void)saveData

    // get paths from root direcory
    NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
    // get documents path
    NSString *documentsPath = [paths objectAtIndex:0];
    // get the path to our Data/plist file
    NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"data.plist"];

    // create dictionary with arrays and their corresponding keys
    NSDictionary *plistDict = [NSDictionary dictionaryWithObjects: [NSArray arrayWithObjects: personalitySliderValue, looksSliderValue, humourSliderValue, chemistrySliderValue, emptySlider, notesValues,nameValues, noValues, ratingValues, nil] forKeys:[NSArray arrayWithObjects: @"personality", @"looks", @"humour", @"chemistry",@"empty",@"notes",@"name",@"no",@"rating", nil]];

    NSString *error = nil;
    // create NSData from dictionary
    NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:plistDict format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];

    // check if plistData exists
    if(plistData)
    
        // write plistData to our Data.plist file
        [plistData writeToFile:plistPath atomically:YES];
    
    else
    
        NSLog(@"Error in saveData: %@", error);
    


我的加载代码:

- (void)loadData

    // get paths from root direcory
    NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
    // get documents path
    NSString *documentsPath = [paths objectAtIndex:0];
    // get the path to our Data/plist file
    NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"data.plist"];

    // check to see if data.plist exists in documents
    if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath])
    
        // if not in documents, get property list from main bundle CHECK D capitalisation
        plistPath = [[NSBundle mainBundle] pathForResource:@"data" ofType:@"plist"];
    

    // read property list into memory as an NSData object
    NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
    NSString *errorDesc = nil;
    NSPropertyListFormat format;
    // convert static property list into dictionary object
    NSDictionary *dictionaryTemp = (NSDictionary *)[NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc];
    if (!dictionaryTemp)
    
        NSLog(@"Error reading plist: %@, format: %d", errorDesc, format);
    
    // assign values
    personalitySliderValue = [NSMutableArray arrayWithArray:[dictionaryTemp objectForKey:@"personality"]];
    looksSliderValue = [NSMutableArray arrayWithArray:[dictionaryTemp objectForKey:@"looks"]];
    humourSliderValue = [NSMutableArray arrayWithArray:[dictionaryTemp objectForKey:@"humour"]];
    chemistrySliderValue = [NSMutableArray arrayWithArray:[dictionaryTemp objectForKey:@"chemistry"]];
    emptySlider = [NSMutableArray arrayWithArray:[dictionaryTemp objectForKey:@"empty"]];
    notesValues = [NSMutableArray arrayWithArray:[dictionaryTemp objectForKey:@"notes"]];
    nameValues = [NSMutableArray arrayWithArray:[dictionaryTemp objectForKey:@"name"]];
    noValues = [NSMutableArray arrayWithArray:[dictionaryTemp objectForKey:@"no"]];
    ratingValues = [NSMutableArray arrayWithArray:[dictionaryTemp objectForKey:@"rating"]];


最后是应用委托方法:

- (void)applicationDidEnterBackground:(UIApplication *)application


    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.


    // save the app data

    [[GlobalData sharedGlobalData]saveData];
    NSLog(@"save method run");




- (void)applicationWillEnterForeground:(UIApplication *)application

    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.

    // load the app data

    [[GlobalData sharedGlobalData]loadData];
    NSLog(@"load method run");

这确实让我把头发拔掉了,所以任何帮助都会很棒!

【问题讨论】:

正如user1885297所说,将其加载到didFinishLaunchingWithOptions。这样,您就可以确信它会在呈现用户界面之前被加载。顺便说一句,如果您完全删除了对 NSData 的引用,并使用 NSDictionary 实例方法 writeToFile 保存并使用类方法 dictionaryWithContentsOfFile 加载,则可以简化代码。 谢谢 Rob,我可能也会进行上述更改,我很难让它正常工作,所以我最终使用了一个可能有点过时的教程。 【参考方案1】:

您可以在此应用委托方法中在启动时加载数据:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
   ....
   [[GlobalData sharedGlobalData] loadData];

【讨论】:

以上是关于保存/加载IOS数据的主要内容,如果未能解决你的问题,请参考以下文章

iOS将UIViews数组保存到文件然后重新加载

Xcode 保存/加载数据

本地保存数据(IOS)

保存和加载 UITableView 数组 - iOS Swift Parse

NSUserDefault 无法在 iOS8 的扩展中保存和加载

无法保存数据 --- Swift、IOS、Core 数据 --- 线程 1:信号 SIGABRT