Как связанный список может быть эффективно сохранен / загружен из файла с использованием Objective-C? - PullRequest
0 голосов
/ 20 марта 2009

После четырех недель изучения Objective-C для iPhone мое первое полезное приложение почти закончено. Однако мне все еще нужно сохранять несколько переменных экземпляра при каждом изменении текущего представления и перезагружать их при повторном открытии представления.

У меня нет проблем с загрузкой переменных с базовыми типами C, такими как int и BOOL , но у меня возникают проблемы со связанным списком, составленным из объектов Objective-C.

Связанный список состоит из памяти, доступ к которой осуществляется тремя указателями: startPointer , currPointer и endPointer . Каждый элемент состоит из указателя last , указателя next , указателя на вложенный связанный список ( nestedPtr ) и некоторых переменных.

Моей первой попыткой было сделать следующее в коде загрузки:

//dataStorageObj will contain the values to be loaded
dataStorageObj = [[DataSaver alloc] init];
NSData *data =[[NSMutableData alloc] initWithContentsOfFile:[documentsDirectory stringByAppendingPathComponent:@"Archive"]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
dataStorageObj = [unarchiver decodeObjectForKey:@"KeyForViewA"];
[unarchiver finishDecoding];
//****************************
//Simple variables loaded here
//****************************
//DataSaver is a class with methods to retrieve its instance variables
//The methods are named after the values they retrieve
startPointer = [dataStorageObj startPointer];
currPointer = [dataStorageObj currPointer];
endPointer = [dataStorageObj endPointer];
[unarchiver release];
[data release];

Я поставил точку отладки в конце, и все переменные имели правильные значения. Фактический доступ к значениям в коде (выполнение в консоли работало) привело к сообщениям EXC_BAD_ACCESS .


Затем я изменил строки загрузки связанного списка на следующие:

startPointer = [[PointerClass alloc] initPointerFromList:[dataStorageObj startPointer]];
currPointer = [[PointerClass alloc] initPointerFromList:[dataStorageObj currPointer]];
endPointer = [[PointerClass alloc] initPointerFromList:[dataStorageObj endPointer]];

Метод initPointerFromList :

-(PointerClass *)initPointerFromList:(PointerClass *)theList
{
    last = theList.last;
    nestedPointer = [[NestedPointerClass alloc] initNestedPointerFromList:theList.nestedPointer];
    //****************************************
    //Other variables loaded from theList here
    //****************************************
    if (theList.next != nil)
    {
        next = [[PointerClass alloc] initPointerFromList:theList.next];
    }

    return self;
}

Теперь проблема заключалась в том, что все указатели указывали на отдельные связанные списки, поэтому я написал методы для извлечения начальной и конечной позиций связанного списка, на который ссылается currPointer:

currPointer = [[PointerClass alloc] initPointerFromList:[dataStorageObj currPointer]];
endPointer = [currPointer lastElement];
startPointer = [currPointer firstElement];

Мой вопрос тройной:

  1. Необходимо ли использовать методы, такие как initPointerFromList , чтобы выделить память для загруженного связанного списка?
  2. Существует ли более эффективный способ поддержания отношений между currPointer , endPointer и startPointer , чем путем поиска в списке с использованием lastElement и firstElement методы?
  3. Что-то не так с методами загрузки кода, которые я представил? Без этого у меня нет проблем; с этим я все еще получаю BAD_ACCESS сообщения. Я хочу знать, связаны ли эти сообщения с кодом загрузки или с тем, как я обрабатывал размещение объектов в остальной части моего приложения.

Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 20 марта 2009

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

http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/Archiving/Archiving.html#//apple_ref/doc/uid/10000047

Если вы не собираетесь использовать NSMutableArray, вы, вероятно, захотите создать контейнерный класс, который отвечает на сообщение encodeWithCoder, и закодировать список таким образом. Вы не собираетесь хранить указатели, а просто использовать их для обхода вашего контейнера и архивировать его в определенном порядке.

1 голос
/ 21 марта 2009

Что вы пытаетесь получить, используя связанный список?

Вы пытаетесь перенести что-то с другого языка в Objective-C, и результаты - это путь к большой работе для того, что вы хотите сделать.

Либо используйте NSArray / NSMutableArray, либо NSDictionary / NSMutableDictionary с ключами для конкретных элементов, которые вы хотите сохранить.

...