使用 NSFilemanager 存储 NSMutableArray 时崩溃

Posted

技术标签:

【中文标题】使用 NSFilemanager 存储 NSMutableArray 时崩溃【英文标题】:Crash when storing NSMutableArray with NSFilemanager 【发布时间】:2012-05-16 08:21:29 【问题描述】:

所以我尝试将数组保存到文件中。这应该在以下代码中完成,但通过调用 addProjectsObject 方法,程序会崩溃并出现以下错误代码:

***** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSConcreteData count]: unrecognized selector sent to instance 0x7eeb800'**

我发布了我认为与问题相关的代码,我还需要提到在同一个 filePath 中存储了另一个文件,它运行良好。我突然想到路径可能是问题,但是由于两个文件的名称不同,这应该不是问题吗?

-(void) addProjectsObject:(NSString *)newProject

    projects = [self getProjectsFromDisk];
    [projects addObject:newProject];
    [self saveProjectsToDisk];

   



-(NSMutableArray *) getProjectsFromDisk

    NSString* filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString* fileName =  @"projects";
    NSString* fileAtPath = [filePath stringByAppendingPathComponent:fileName];

    if(![[NSFileManager defaultManager] fileExistsAtPath:fileAtPath])
    
        [[NSFileManager defaultManager] createFileAtPath:fileAtPath contents:nil attributes:nil];

    NSMutableArray* temp = [[NSMutableArray alloc]initWithArray:[NSData dataWithContentsOfFile:fileAtPath]]; 

    return temp;



-(void) saveProjectsToDisk 

    NSString* filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString* fileName =  @"projects";
    NSString* fileAtPath = [filePath stringByAppendingPathComponent:fileName];

    if(![[NSFileManager defaultManager] fileExistsAtPath:fileAtPath])
    
        [[NSFileManager defaultManager] createFileAtPath:fileAtPath contents:nil attributes:nil];


    [projects writeToFile:fileAtPath atomically:NO];


【问题讨论】:

您是否尝试过调试应用程序崩溃的确切时间? 正如 Saad 所说,问题似乎出在这一行: NSMutableArray* temp = [[NSMutableArray alloc]initWithArray:[NSData dataWithContentsOfFile:fileAtPath]];我似乎错过了一些关于数据类型的东西,但我完全不知道它可能是什么 【参考方案1】:

NSData不是 NSArray

[[NSMutableArray alloc]initWithArray:] 需要一个 NSArray 的实例。[NSData dataWithContentsOfFile:fileAtPath] 返回一个 NSData 的实例。 这两个不能一起工作。

如果projectsNSMutableArray,只需使用:

NSMutableArray* temp = [NSMutableArray arrayWithContentsOfFile:fileAtPath];

其余的代码也可以被剥离。无需检查文件是否存在,甚至无需在两行之后创建一个文件来覆盖它。

这也可以:

- (NSMutableArray *)projectsFromDisk 
    NSString* filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString* fileName =  @"projects";
    NSString* fileAtPath = [filePath stringByAppendingPathComponent:fileName];
    NSMutableArray* temp = [NSMutableArray arrayWithContentsOfFile:fileAtPath];
    if (!temp) 
        // if file can't be read (does not exist, or invalid format) create an empty array
        temp = [NSMutableArray array];
    
    return temp;


- (void)saveProjectsToDisk 
    NSString* filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString* fileName =  @"projects";
    NSString* fileAtPath = [filePath stringByAppendingPathComponent:fileName];
    [projects writeToFile:fileAtPath atomically:NO];

【讨论】:

非常感谢,这帮助很大,我现在看得更清楚了。【参考方案2】:

这是因为您分配了不合适的指针,您将 NSConcreteData 对象指针分配给 NSMutablearray 并尝试调用某些数组方法,因此发生这种情况

【讨论】:

那么正确的程序是什么?我必须以某种方式转换数据吗? [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray] 试试这个它会返回一个数组 哈哈哈。我不是先生,只是像你这样的开发人员。 :) 随时询问。 Skype:the_saad1

以上是关于使用 NSFilemanager 存储 NSMutableArray 时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 NSFileManager 将 UIImage 保存到文件中?

将自定义对象转换为 NSData 以与 NSFileManager 一起使用

NSFileManager 唯一的文件名

使用核心数据将数据存储到 sqlite 表的问题

NSFileManager&&NSFileHandle

IOS--文件管理NSFileManager