2016-02-02 5 views
-1

Мне нужно сохранить много NSMutableArray с моими пользовательскими объектами, и я хочу знать, что это лучший способ сделать это.Сохранить NSMutableArray в iOS

Возможно, NSUserDefaults - это не лучший способ сделать это.

Что следует использовать?

ответ

2

Если массив содержит без Plist объектов, then you cannot use NSUserDefaults without first encoding the array.

The value parameter can be only property list objects: NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. For NSArray and NSDictionary objects, their contents must be property list objects.

Вы хотите, чтобы закодировать его using NSKeyedArchiver. Это даст вам NSData объект, который вы можете сохранить в NSUserDefaults, или записать его в файл через NSKeyedArchiver.

Все, что вам нужно сделать, это соответствует NSCoding в пользовательском объекте, и переопределить initWithCoder: чтобы инициализировать ваш объект, когда он будет загружен и encodeWithCoder: закодировать переменные, когда это будет закодирован. Например, пользовательский объект будет выглядеть примерно так:

@interface customArrayObject : NSObject <NSCoding> 

@property (nonatomic) NSString* foo; 

@property (nonatomic) NSInteger bar; 

@end 

@implementation customArrayObject 

-(instancetype) initWithCoder:(NSCoder *)aDecoder { // decode variables 
    if (self = [super init]) { 
     _foo = [aDecoder decodeObjectForKey:@"foo"]; 
     _bar = [aDecoder decodeIntegerForKey:@"bar"]; 
    } 
    return self; 
} 

-(void) encodeWithCoder:(NSCoder *)aCoder { // encode variables 
    [aCoder encodeObject:_foo forKey:@"foo"]; 
    [aCoder encodeInteger:_bar forKey:@"bar"]; 
} 

@end 

Стоит также отметить, что NSUserDefaults используется для хранения пользовательских предпочтения, и, следовательно, если массив содержит данные, которые никоим образом не делать с предпочтением пользователя, вы не должны использовать NSUserDefaults - вы должны сами записывать его на диск.

Написание вашего массива на диск на самом деле намного более тривиально, чем кажется, вы можете использовать метод archiveRootObject:toFile: на NSKeyedArchiver. Например, это будет написать свой собственный массив в каталог документов:

// Gets the documents directory path 
NSString* documentsPath = NSSearchPathForDirectoriesInDomains(directory, NSUserDomainMask, YES)[0]; 

// Archive and save the file to foo.dat in the documents directory. Returns whether the operation was successful. 
BOOL success = [NSKeyedArchiver archiveRootObject:customArray toFile:[NSString stringWithFormat:@"%@/%@", documentsPath, @"foo.dat"]] 

Однако стоит также не отметить, что эта квартира (да/нет), была ли операция успешной не так уж велика, когда это касается обработки ошибок. Если вы хотите реализовать пользовательскую обработку ошибок, то сначала вы должны закодировать объект с использованием метода NSKeyedArchiverarchivedDataWithRootObject:, а затем NSDatawriteToFile:options:error:.

+1

'NSKeyedArchiver' имеет метод архивирования непосредственно в файл, поэтому вы можете использовать его вместо того, чтобы преобразовывать его в данные и затем записывать в файл в отдельный вызов. – dan

+0

поэтому! никогда не видел этого раньше ... Я обновляю свой ответ за секунду. Хотя, лично я бы предпочел использовать подход «NSData», поскольку он имеет гораздо больше возможностей для обработки ошибок. 'NSKeyedArchiver' просто возвращает плоскую да или нет, работает ли она. – Hamish

+0

Это правда, хотя 'writeToFile: atomically' также просто возвращает yes/no. Используйте 'writeToFile: options: error:', если вы хотите получить более подробную информацию об ошибке. – dan

Смежные вопросы