Ios8 写入documentsDirectory的对象的非持久性-为

Ios8 写入documentsDirectory的对象的非持久性-为,ios8,nscoding,Ios8,Nscoding,--有关如何使保存到documents目录的对象在驱动器上持久化并在重新启动iDevice后可恢复的问题 这是我的问题。我用NSCoding创建一个数据对象,并用数据填充它。每次更新对象中的数据时,我都会将其写入documentsDirectory。我停止应用程序并再次启动应用程序,并且我的数据对象与它的所有数据保持一致。但是,如果我重新启动iPhone,我为恢复和读取数据对象而编写的代码就会失败 我编写的代码最初仅使用NSString作为文件路径。它在ios7下运行良好,但在ios8下失败 在

--有关如何使保存到documents目录的对象在驱动器上持久化并在重新启动iDevice后可恢复的问题

这是我的问题。我用NSCoding创建一个数据对象,并用数据填充它。每次更新对象中的数据时,我都会将其写入documentsDirectory。我停止应用程序并再次启动应用程序,并且我的数据对象与它的所有数据保持一致。但是,如果我重新启动iPhone,我为恢复和读取数据对象而编写的代码就会失败

我编写的代码最初仅使用NSString作为文件路径。它在ios7下运行良好,但在ios8下失败

在阅读相关资料时,我从苹果的文档中发现了以下线索:

“重要提示:虽然在应用程序运行时可以安全使用,但在应用程序启动之间存储和重用文件引用URL并不安全,因为如果系统重新启动,文件的ID可能会更改。如果要在应用程序启动之间持久存储文件位置,请按照“使用书签定位文件”中的说明创建书签。“

因此,我重写了我的ios7文件打开和文件关闭方法,使它们不再使用字符串或URL,而是从使用NSUserDefaults保存的书签中获取字符串和URL。同样的问题:只要我不关机,一切正常,但一旦关机,一切都会丢失。我无法解决这个问题

以下是我当前的一系列步骤。首先,我使用书签确定(或者如果NSUsrDefaults中已经存在,则恢复)documentsDirectory的绝对路径:

 + (NSString*) getGeoModelAbsolutePath
 {
     NSString *path;
     NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
     NSURL *documentsDirectoryBookmarkURL;
     NSData* documentsDirectoryBookmark = [userDefaults objectForKey:@"documentDirectoryBookmark"];
     if(documentsDirectoryBookmark == nil)
     {
         documentsDirectoryBookmarkURL = [self getDocumentsDirectoryURL];
         documentsDirectoryBookmark = [self bookmarkForURL:documentsDirectoryBookmarkURL];
     }
     documentsDirectoryBookmarkURL = [self urlForBookmark:documentsDirectoryBookmark];
     path = documentsDirectoryBookmarkURL.path;
     path = [path stringByAppendingString:@"/Model.mod"];

     return path;
 }
使用从我的ios7代码(仅使用getDocumentsDirectory方法)修改的方法:

现在我有了一个带有模型文件名的NSString路径,我可以用它来访问模型

 - (GeoModel*) openGeoModel
 {

     GeoModel *geoModel;
     NSString* documentsDirectoryGeoModel =[FileManager getGeoModelAbsolutePath];



     if([FileManager fileExistsAtAbsolutePath:documentsDirectoryGeoModel])
     {

         NSData* data = [NSData dataWithContentsOfFile: documentsDirectoryGeoModel]; //]documentsDirectoryGeoModel];
         geoModel = [NSKeyedUnarchiver unarchiveObjectWithData: data];
         NSString *unarchivedGeoModelVersion = geoModel.geoModel_VersionID;

         if(![unarchivedGeoModelVersion isEqual: currentGeoModelVersion])
         {
             [FileManager deleteFile:documentsDirectoryGeoModel];
             geoModel = [GeoModel geoModelInit];
             [Utilities setGeoProjectCounter:0];
         }

     }
     else
     {
         geoModel  = [GeoModel geoModelInit];
     }

     [FileManager saveGeoModel];
     return geoModel;

 }
然后我可以将其保存到Documents目录,如下所示:

 + (BOOL)saveGeoModel
 {

     NSError *error = nil;
     NSString *path = [self getGeoModelAbsolutePath];
     [NSKeyedArchiver archiveRootObject:appDelegate.currentGeoModel toFile:path];

     NSData* encodedData = [NSKeyedArchiver archivedDataWithRootObject: appDelegate.currentGeoModel];
     BOOL success = [encodedData writeToFile: path options:NSDataWritingAtomic error:&error];

  return success;  
 }
这总是成功的——但只有在我不关闭设备的情况下,它才是持久的!我在这方面没有任何进展:任何帮助都将不胜感激

提前谢谢


蒂姆·雷德菲尔德(Tim Redfield)

在那里。我认为答案是正确的——除非其他人对如何改进上述列表有意见,否则它们确实可以正常工作!

对。我认为这不符合回答我自己的问题的条件——因为我犯的错误不在这段代码中。(我没有按正确的顺序保存数据:(续)--我提前保存了,所以数据对象中没有任何内容:未归档的内容为零。(抱歉--键盘敏感).我的观点:上述代码实际上运行得很好,而且是持久性的——只要您以正确的顺序将数据对象写入documentDirectory,使其包含数据,并且不是零。在上面的示例中,我的本地Geomedel实例包含数据,但由于我过早地保存了数据,我的应用程序的其余部分看到的是一个id不存在。对于寻找类似答案的任何人来说,还有一点需要注意:一个更短的方法可以是:本数据*encodedData=[NSKeyedArchiver archivedDataWithRootObject:gemoodell];NSUserDefaults*userDefaults=[NSUserDefaults standardUserDefaults];[userDefaults setObject:encodedData-forKey:@“Archivedgemoodel”];[用户默认同步];
 + (NSData*)bookmarkForURL:(NSURL*)url {
     NSError* theError = nil;
     NSData* bookmark = [url bookmarkDataWithOptions:NSURLBookmarkCreationSuitableForBookmarkFile
                      includingResourceValuesForKeys:nil
                                       relativeToURL:nil
                                               error:&theError];
     if (theError || (bookmark == nil)) {
         // Handle any errors.
         return nil;
     }
     return bookmark;
 }
 - (GeoModel*) openGeoModel
 {

     GeoModel *geoModel;
     NSString* documentsDirectoryGeoModel =[FileManager getGeoModelAbsolutePath];



     if([FileManager fileExistsAtAbsolutePath:documentsDirectoryGeoModel])
     {

         NSData* data = [NSData dataWithContentsOfFile: documentsDirectoryGeoModel]; //]documentsDirectoryGeoModel];
         geoModel = [NSKeyedUnarchiver unarchiveObjectWithData: data];
         NSString *unarchivedGeoModelVersion = geoModel.geoModel_VersionID;

         if(![unarchivedGeoModelVersion isEqual: currentGeoModelVersion])
         {
             [FileManager deleteFile:documentsDirectoryGeoModel];
             geoModel = [GeoModel geoModelInit];
             [Utilities setGeoProjectCounter:0];
         }

     }
     else
     {
         geoModel  = [GeoModel geoModelInit];
     }

     [FileManager saveGeoModel];
     return geoModel;

 }
 + (BOOL)saveGeoModel
 {

     NSError *error = nil;
     NSString *path = [self getGeoModelAbsolutePath];
     [NSKeyedArchiver archiveRootObject:appDelegate.currentGeoModel toFile:path];

     NSData* encodedData = [NSKeyedArchiver archivedDataWithRootObject: appDelegate.currentGeoModel];
     BOOL success = [encodedData writeToFile: path options:NSDataWritingAtomic error:&error];

  return success;  
 }