2009-03-20 7 views
0

Nach vier Wochen des Lernens von Objective-C für das iPhone ist meine erste nützliche Anwendung fast fertig. Ich muss jedoch immer noch mehrere Instanzvariablen speichern, wenn die aktuelle Ansicht geändert wird, und sie erneut laden, wenn die Ansicht erneut geöffnet wird.Wie kann eine verkettete Liste effizient aus einer Datei mit Objective-C gespeichert/geladen werden?

Ich habe keine Probleme Laden von Variablen mit grundlegenden C-Typen wie int und BOOL, aber habe Schwierigkeiten mit einer verknüpften Liste aus Objective-C-Objekten.

der verketteten Liste besteht aus Speicher durch drei Zeiger zugegriffen: startPointer, currPointer und Endzeiger. Jedes Element besteht aus einem letzten Zeiger, einem nächsten Zeiger, einem Zeiger auf eine verschachtelte verkettete Liste (nestedPtr), und einige Variablen.

Mein erster Versuch war die folgend in der Lade Code zu tun:

//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]; 

ich einen Debug-Punkt am Ende platziert und alle Variablen hatten die richtigen Werte. Der Zugriff auf die Werte im Code (dies geschah in der Konsole) führte zu EXC_BAD_ACCESS Nachrichten.


Als nächstes änderte ich die Liste verknüpft Ladeleitungen auf die folgenden:

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

Die initPointerFromList Methode:

-(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; 
} 

Das Problem war nun, dass die Zeiger alle Zeige waren zu einzelnen verknüpften Listen, also habe ich Methoden geschrieben, um die Anfangs- und Endpositionen der verknüpften Liste abzurufen, auf die currPointer verweist:

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

Meine Frage ist dreifach:

  1. Ist es notwendig, Methoden zu verwenden, wie initPointerFromList Speicher für eine geladene verknüpften Liste zuzuordnen?
  2. Gibt es eine effizientere Art und Weise die Beziehung zwischen currPointer, Endzeiger und startPointer als durch die Suche durch die Liste mit dem lastElement und first Methoden zu halten?
  3. Ist etwas falsch mit den Techniken hinter dem Ladecode, den ich vorgestellt habe? Ohne es habe ich keine Probleme; damit bekomme ich immer noch BAD_ACCESS Nachrichten. Ich möchte wissen, ob diese Nachrichten an den Ladecode gebunden sind oder ob ich die Objektzuordnung im Rest meiner Anwendung so gehandhabt habe.

Vielen Dank im Voraus!

Antwort

2

Zeiger neigen dazu, ein wunder Punkt von Archiven zu sein, wie Sie entdeckt haben. Ist es möglich, dass Sie NSMutableArray für Ihre Speicheranforderungen verwenden, da dies die Angelegenheit für Sie vereinfachen könnte?

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

Wenn Sie nicht verwenden NSMutableArray gehen, wollen Sie wahrscheinlich eine Container-Klasse erstellen, die auf die encodeWithCoder Nachricht reagiert, und codieren die Liste, die Art und Weise. Sie werden die Zeiger nicht speichern, sondern sie verwenden, um Ihren Container zu navigieren und in einer deterministischen Reihenfolge zu archivieren.

+0

Vielen Dank für Ihre schnelle Antwort. Ich werde versuchen, NSMutableArray zu verwenden. – user80495

1

Was möchten Sie mit einer verknüpften Liste erreichen?

Sie versuchen, etwas von einer anderen Sprache in Objective-C zu schuhen, und die Ergebnisse sind viel zu viel Arbeit für das, was Sie tun möchten.

Verwenden Sie entweder ein NSArray/NSMutableArray oder ein NSDictionary/NSMutableDictionary mit Schlüsseln für bestimmte Elemente, die Sie speichern möchten.

+0

Mir war nicht bewusst, dass verknüpfte Listen in Ziel C vermieden werden sollten. Ich habe lange nicht in C-basierten Sprachen codiert. Ich nehme an, dass der einzige Grund, warum ich eine verknüpfte Liste verwendete, dass es zu dieser Zeit am einfachsten schien. Leider ist die verknüpfte Liste so stark an meine App gebunden, dass ich wahrscheinlich neu starten muss. – user80495

+0

Wenn die Verwendung einer verknüpften Liste speziell statt einer geordneten Sammlung so eng mit dem Rest Ihrer Anwendung verknüpft ist, ist es wahrscheinlich eine gute Idee, einen Schritt zurückzutreten und zu überdenken, wie Sie sie entwickeln. Wenn es um echte Objektmodellierung geht, sollte es nicht schwer sein, eines für das andere zu ersetzen. –

+0

Ich sehe nicht, warum Sie neu starten müssten - der Kopf ist 0, das Ende-Element ist das Ende des Arrays, und Sie könnten einen Zeiger auf Ihr "aktuelles" Element halten ... In der Tat würde es Seien Sie einfach, NSArray von der Unterklasse abzusetzen, um Ihnen verknüpfte Listen wie Accessoren zu geben. Sie können es nicht mit einer Kategorie machen, um einen aktuellen Zeiger zu behalten. –

Verwandte Themen