2009-03-20 3 views
0

Objective-CをiPhoneで4週間学習した後、私の最初の便利なアプリケーションはほぼ完成しました。しかし、現在のビューが変更されたときはいつでも、いくつかのインスタンス変数を保存し、ビューを再オープンしたときにインスタンス変数をリロードする必要があります。Objective-Cを使用してリンクリストをファイルから効率的に保存/ロードする方法はありますか?

私はint型BOOLのような基本的なC型との支障ローディング変数を持っていませんが、Objective-Cのオブジェクトで作られたリンクリストの難しさを持っています。 startPointercurrPointer、およびendPointer

リンクリストは、3つのポインタによってアクセスされるメモリで構成されています。 各要素は、の最後のポインタ、の次のポインタ、ネストされたリンクリストへのポインタ(、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]; 

私の質問は3つあり:

  1. それがロードされたリンクリスト用のメモリを割り当てるために、このようなinitPointerFromListなどのメソッドを使用する必要ですか?
  2. 方法lastElementfirstElementを使用してリストを検索することによって、よりcurrPointerendPointer、およびstartPointerとの関係を維持するためのより効率的な方法はありますか?
  3. 私が提示したローディングコードの背後にある技術に何か問題はありますか?それがなければ問題はありません。それで、私はまだBAD_ACCESSメッセージを得る。これらのメッセージがローディングコードに縛られているかどうか、またはアプリケーションの残りの部分でオブジェクトの割り当てを処理したかどうかを知りたいです。

ありがとうございます!

答えて

2

あなたが発見したように、ポインタはアーカイブの痛みを感じる傾向があります。 NSMutableArrayをストレージ要件に使用することは可能ですか?これにより、問題が簡単になる可能性があります。

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

あなたはNSMutableArrayのを使用するつもりはない場合は、おそらくencodeWithCoderメッセージに応答するコンテナクラスを作成し、そのようにリストをエンコードしたいです。あなたはポインタを格納するつもりはなく、それらを使ってコンテナを歩いて、決定的な順序でアーカイブします。

+0

ご協力いただきありがとうございます。私はNSMutableArrayを使用しようとします。 – user80495

1

リンクリストを使用して何を得ようとしていますか?

あなたはObjective-Cに別の言語のものを靴ひねりをかけようとしています。その結果は、あなたがしたいことに対して大いに役立ちます。

NSArray/NSMutableArray、または格納しようとしている特定の要素のキーを持つNSDictionary/NSMutableDictionaryを使用します。

+0

私はObjective Cでリンクリストを避けるべきであることに気づいていませんでした。私はCベースの言語で長い間コーディングしていません。私は、リンクされたリストを使用していた唯一の理由は、当時最も簡単だったと思った。残念なことに、リンクされたリストは私のアプリに深く結びついているので再起動する必要があります。 – user80495

+0

リンクされたリストを具体的に使用する場合は、順序付けされたコレクションだけでなく、アプリケーションの残りの部分と緊密に結びついている場合は、一歩踏み出して開発方法を再検討することをお勧めします。実際のオブジェクトモデリングを行う場合は、もう一方を置き換えるのは難しくありません。 –

+0

なぜ再起動する必要があるのか​​わかりません。先頭が0で、最後の要素が配列の最後で、現在の要素へのポインタを保持できます... NSArrayをサブクラス化して、リンクされたリストのようなアクセサを簡単に作成できます。現在のポインタを保持するカテゴリではできません。 –

関連する問題