开发者

Why doesen't it work to write this NSMutableArray to a plist?

edited.

Hey, I am trying to write an NSMutableArray to a plist. The compiler does not show any errors, but it does not write to the plist anyway. I have tried this on a real device too, not just the Simulator.

Basically, what this code does, is that when you click the accessoryView of a UITableViewCell, it gets the indexPath pressed, edits an NSMutableArray and tries to write that NSMutableArray to a plist. It then reloads the arrays mentioned (from multiple plists) and reloads the data in a UITableView from the arrays.

Code:

NSIndexPath *indexPath = [table indexPathForRowAtPoint:[[[event touchesForView:sender] anyObject] locationInView:table]];

[arrayFav removeObjectAtIndex:[arrayFav indexOfObject:[NSNumber numberWithInt:[[arraySub objectAtIndex:indexPath.row] intValue]]]];

NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *plistPath = [rootPath stringByAppendingPathComponent:@"arrayFav.plist"];
NSLog(@"%@ - %@", rootPath, plistPath); 


[arrayFav writeToFile:plistPath atomically:YES];    

// Reloads data into the arrays
[self l开发者_如何学PythonoadDataFromPlists];

// Reloads data in tableView from arrays
[tableFarts reloadData];

CFShow() on the array after removing one of them shows this:

<CFArray 0x6262110 [0x2c810a0]>{type = mutable-small, count = 4, values = (
    0 : <CFNumber 0x6502e10 [0x2c810a0]>{value = +3, type = kCFNumberSInt32Type}
    1 : <CFNumber 0x6239de0 [0x2c810a0]>{value = +8, type = kCFNumberSInt32Type}
    2 : <CFNumber 0x6239dc0 [0x2c810a0]>{value = +10, type = kCFNumberSInt32Type}
    3 : <CFNumber 0x6261420 [0x2c810a0]>{value = +40, type = kCFNumberSInt64Type}

DEBUG-INFO: writeToPlist shows YES, I have tried to release all the arrays before filling them up again, setting them to nil, set atomically to NO.


As discussed in the comments below, the actual problem here is that the plist is being read from and written to two different locations. Somewhere in the app, there is code that reads the file into the array similar to this:

NSString *plistFavPath = [[NSBundle mainBundle] pathForResource:@"arrayFav" 
                                                         ofType:@"plist"]; 
arrayFav = [[NSMutableArray alloc] initWithContentsOfFile:plistFavPath];

This logic reads the array from the application's bundle, which is a read-only location and part of the distributed app. Later when the edited array is persisted, code similar to this is used:

NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                          NSUserDomainMask,
                                                          YES) objectAtIndex:0];
NSString *plistPath = [rootPath 
                          stringByAppendingPathComponent:@"arrayFav.plist"];
NSLog(@"%@ - %@", rootPath, plistPath); 
[arrayFav writeToFile:plistPath atomically:YES];   

The result here is that the updated file gets written to the app's documents directory, but it is never read from there, giving the appearance that the file is not being saved correctly. To correct this, you should change the code that reads the file to use the same path that you are writing to.

If you need to distribute a default version of the plist for use on the initial launch before the array has been edited, you could continue to include a version of the file in your bundle and then add code to your app delegate that check if the file exists in the documents directory and if it is not present, copies the bundle's default version of the file to the proper place.


[yourMutableArray writeToFile:fileName atomically:YES];

This should work. NSMutableArray inherits from NSArray which has a method to write to a plist.


writeToFile:atomically: won't work if your array contains custom objects.

If your array contains custom objects that are not Plist objects (NSArray, NSDictionary, NSString, NSNumber, etc), then you will not be able to use this method. This method only works on Plist objects.

Another option would be to use the NSCoding protocol, and write your objects to disk that way.


Yes

Look at the Property List Programming Guide.

phoneNumbers is a NSMutableArray

- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
    NSString *error;
    NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *plistPath = [rootPath stringByAppendingPathComponent:@"Data.plist"];
    NSDictionary *plistDict = [NSDictionary dictionaryWithObjects:
            [NSArray arrayWithObjects: personName, phoneNumbers, nil]
            forKeys:[NSArray arrayWithObjects: @"Name", @"Phones", nil]];
    NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:plistDict
                            format:NSPropertyListXMLFormat_v1_0
                            errorDescription:&error];
    if(plistData) {
        [plistData writeToFile:plistPath atomically:YES];
    }
    else {
        NSLog(error);
        [error release];
    }
    return NSTerminateNow;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜