Цель-C: сохранение объектов, сериализация и NSCoding - PullRequest
0 голосов
/ 15 февраля 2011

Прочитайте этот код.Я написал это за столом за 5 минут, это не рабочий код, а просто для галочки.Затем прочитайте мой вопрос внизу:

@interface SomeClass : NSObject {

NSString *currentFruit;
NSMutableArray *fruits;

}

@property (retain) NSString *currentFruit;
@property (retain) NSMutableArray *fruits;

@end

@implementation SomeClass
@synthesize currentFruit, fruits;

-(void) createArray {

    self.fruits = [[NSMutableArray alloc] initWithObjects:@"apples",@"oranges",@"grapes",nil];
    self.currentFruit = [fruits objectAtIndex:0];
}

-(void)writeToDisk {
    NSString *filePath = @"/somePath/file.ext";
    NSMutableData *fileData = [NSMutableData data];
    NSKeyedArchiver *coder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:fileData];
    [coder encodeObject:self.fruits forKey:@"fruitArray"];
    [coder encodeObject:self.currentFruit forKey:@"theFruit"];
    [coder finishEncoding];
    [fileData writeToFile:filePath atomically:YES];
    [coder release];
}

-(void)loadDataFromDisk {
    NSString *filePath = @"/somePath/file.ext";
    NSData *fileData = [[NSData alloc] initWithContentsOfFile:filePah];
    NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:fileData];
    NSMutableArray *decodedFruits = [decoder decodeObjectForKey:@"fruitArray"];
    NSString *decodedFruit = [decoder decodeObjectForKey:@"theFruit"];
    self.currentFruit = decodedFruit;
    self.fruits = decodedFruits;
    [decoder release];
    [fileData release];
}

Скажем, я использовал метод - (void) createArray, чтобы создать мой массив, а затем установил экземпляр currentFruit для первого объекта в массиве.Затем я использовал - (void) writeDataToDisk и сохранил объекты в файл.Когда я использую loadDataFromDisk, знает ли мое приложение, что currentFruit должен быть объектом в начале массива фруктов?или у меня сейчас будет два отдельных экземпляра?

Я пытаюсь это выяснить.Должен ли я отслеживать индекс массива вместо отслеживания реальных объектов?Я хочу всегда ссылаться на объект в массиве.Имеет ли это смысл?

Ответы [ 2 ]

2 голосов
/ 15 февраля 2011

Попробуйте настроить интерфейс в соответствии с протоколом NSCoding.

Реализация encodeWithCoder и initWithEncoder.Затем вы можете сериализовать и десериализовать объект в файл или поток.

Затем выполните следующее утверждение:

NSData *data = [NSKeyedarchiver archivedDataWithRootObject:someClassInstance];

или

SomeClass *instance = [NSKeyedUnarchiver unarchiveObjectWithData:data];

Это не 'T ответить на ваш вопрос.Но сделает ваш код более приятным.

Теперь ваш вопрос: ваше приложение не «знает» текущий фрукт.Поскольку loadDataFromDisk находится в области действия экземпляра, переменные экземпляра переопределяются.Другими словами: у вас есть экземпляр, для которого вы будете вызывать метод.Его содержание изменится и второго экземпляра не будет.Если вы хотите, чтобы два экземпляра использовали протокол NSCoding

Если вы хотите, чтобы ваш currentfruit распределялся между несколькими экземплярами, сделайте переменную currentfruit статической.

1 голос
/ 15 февраля 2011

РЕДАКТИРОВАТЬ: я забрал следующий ответ, как-то не поняв, что вы не используете NSCoder. Нижеследующее относится к кодированию путем реализации NSCoding и предоставления только одного корневого объекта. Если то, что вы хотите, сработает в вашем случае, это будет деталь реализации вне документации, и поэтому на нее не следует полагаться.

Я склонен полагать, что вы получите тот же объект; архиваторы обнаруживают, когда вы выписываете несколько экземпляров одного и того же объекта, и используете ссылку на оригинал. В противном случае они не смогли бы записать какую-либо иерархию объектов, включающую циклическую ссылку, - они просто навсегда записали бы на диск. Поэтому информация о том, что объект 'theFruit' взят из массива 'fruitArray', закодирована в архиве. См. «Корневой объект» в Руководстве по программированию архивов и сериализации .

Учитывая, что вы сохраняете один и тот же экземпляр NSKeyedUnarchiver, вполне логично предположить, что приведенный ниже код будет достаточно умен, чтобы возвращать тот же объект. Тем не менее, я читаю между строк в центре внимания Apple по сохранению графа объектов и не могу найти явного подтверждения этому.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...