Мне нужно сохранить много NSMutableArray с моими пользовательскими объектами, и я хочу знать, что это лучший способ сделать это.Сохранить NSMutableArray в iOS
Возможно, NSUserDefaults - это не лучший способ сделать это.
Что следует использовать?
Мне нужно сохранить много NSMutableArray с моими пользовательскими объектами, и я хочу знать, что это лучший способ сделать это.Сохранить NSMutableArray в iOS
Возможно, NSUserDefaults - это не лучший способ сделать это.
Что следует использовать?
Если массив содержит без 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"]]
Однако стоит также не отметить, что эта квартира (да/нет), была ли операция успешной не так уж велика, когда это касается обработки ошибок. Если вы хотите реализовать пользовательскую обработку ошибок, то сначала вы должны закодировать объект с использованием метода NSKeyedArchiver
archivedDataWithRootObject:
, а затем NSData
writeToFile:options:error:
.
'NSKeyedArchiver' имеет метод архивирования непосредственно в файл, поэтому вы можете использовать его вместо того, чтобы преобразовывать его в данные и затем записывать в файл в отдельный вызов. – dan
поэтому! никогда не видел этого раньше ... Я обновляю свой ответ за секунду. Хотя, лично я бы предпочел использовать подход «NSData», поскольку он имеет гораздо больше возможностей для обработки ошибок. 'NSKeyedArchiver' просто возвращает плоскую да или нет, работает ли она. – Hamish
Это правда, хотя 'writeToFile: atomically' также просто возвращает yes/no. Используйте 'writeToFile: options: error:', если вы хотите получить более подробную информацию об ошибке. – dan