【问题标题】:Saving Array To File Objective C将数组保存到文件目标 C
【发布时间】:2012-06-22 15:21:22
【问题描述】:

我一直被困在这个问题上,我终于弄明白了,现在它突然又停止工作了......

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:@"%@/scoreCards.dgs",documentsDirectory];

NSMutableArray *savedArrayOfScorecards = [[NSMutableArray alloc]init];
savedArrayOfScorecards = [NSMutableArray arrayWithContentsOfFile:filePath];
[savedArrayOfScorecards addObject:currentScoreCard];

[savedArrayOfScorecards writeToFile:filePath atomically:YES];

甚至没有创建文件 scoreCards.dgs...

我做错了什么?

【问题讨论】:

  • 您在使用 ARC 吗?如果不是,您的内存泄漏为savedArrayOfScorecards。

标签: iphone objective-c ios ios5 nsarray


【解决方案1】:

这里可能会出现一些问题。

1) 您存储在数组中的数据类型可能无法编码或归档到文件中。而且您包含的代码 sn-p 并没有很好地提示您要保存哪种数据。如果您的数组中有自定义对象(即不是 NSString、NSNumber、NSDate 等的东西),那么这肯定是问题所在。 There are plenty of questions here on StackOverflow 可能会帮助您解决此问题。

2) 您的阵列的文件路径可能是伪造的。例如,您没有检查“documentsDirectory”是否为 nil、有效或可写。

3) 也有可能,但不太可能,“savedArrayOfScorecards”可能是一个 nil 数组。您应该进行错误检查以确保“savedArrayOfScorecards”已被实例化并且数组中有多个对象。

【讨论】:

    【解决方案2】:

    您的问题是,尽管您创建了一个数组,但在读取文件之前,它在您的调用中被 nil-ed:

    savedArrayOfScorecards = [NSMutableArray arrayWithContentsOfFile:filePath];
    

    所以,因为这个 savedArrayOfScorecards 现在是 nil,所以你把它写入文件的调用没有做任何事情。 您应该将数组加载到另一个变量,并检查它是否为 nil,并且仅当从文件中读取的变量为 nil 时才创建新数组。像这样的:

    NSMutableArray *savedArrayOfScorecards = [NSMutableArray arrayWithContentsOfFile:filePath];
    if (!savedArrayOfScorecards) {
        savedArrayOfScorecards = [[NSMutableArray alloc]init];
    }
    

    【讨论】:

    • 它为 nil 的唯一原因是文件路径的内容本身是否为 nil,如果他存档,则不会是真的。
    • @CodaFi 还有另一个原因 -> NSArray 无法解析文件的内容,因为它们包含无效的对象或其他东西。
    • Apple 文档说明如下:“如果文件无法打开或文件内容无法解析为数组,则返回 nil。”因此,如果文件不存在,因此无法打开,arrayWithContentsOfFile 将返回 nil。
    【解决方案3】:

    加载时确定文件存在吗?

    savedArrayOfScorecards = [NSMutableArray arrayWithContentsOfFile:filePath];
    

    这一行从文件中创建了一个新的 NSMutableArray。如果文件不存在,则返回 nil。 writeToFile 然后被发送到 nil 并且什么都不会发生。

    添加一个检查是否为nil,如果是则创建一个新数组:

    NSMutableArray *savedArrayOfScorecards = [NSMutableArray arrayWithContentsOfFile:filePath];
    if(savedArrayOfScorecards == nil) savedArrayOfScorecards = [NSMutableArray array];
    [savedArrayOfScorecards addObject:currentScoreCard];
    
    [savedArrayOfScorecards writeToFile:filePath atomically:YES];
    

    【讨论】:

      【解决方案4】:

      NSMutableArray 不是符合属性列表的格式。您必须使用 NSArchiver 使其符合 plist。

      NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
      NSString *documentsDirectory = [paths objectAtIndex:0];
      NSString *filePath = [NSString stringWithFormat:@"%@/scoreCards.dgs",documentsDirectory];
      
      NSMutableArray *savedArrayOfScorecards = [[NSMutableArray alloc]init];
      savedArrayOfScorecards = [NSMutableArray arrayWithContentsOfFile:filePath];
      [savedArrayOfScorecards addObject:@"ALLLAALLAAALLA"];
      
      NSMutableData *data = [NSMutableData data];
      NSKeyedArchiver *archive = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
      [archive encodeObject:savedArrayOfScorecards forKey:@"Scorecards"];
      [archive finishEncoding];
      
      BOOL result = [data writeToFile:filePath atomically:YES];
      
      NSLog(result ? @"YES" : @"NO");
      

      【讨论】:

        【解决方案5】:

        正确的答案已经在这里,只是添加一个更好的解决方案:

        NSFileManager* fileManager = [NSFileManager defaultManager];
        NSMutableArray* array;
        
        if ([fileManager fileExistsAtPath:filePath]) {
            array = [NSMutableArray arrayWithContentsOfFile:filePath];
        
            NSAssert(array != nil, @"Invalid data in file.");
        }
        else {
            array = [[NSMutableArray] alloc] init];
        }
        
        [array addObject:currentScoreCard];
        [array writeToFile:filePath atomically:YES];
        
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-06-30
          • 1970-01-01
          • 1970-01-01
          • 2019-06-07
          • 2015-08-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多