0

iPhone 用の Objective-C を 4 週間学習した後、私の最初の有用なアプリケーションはほぼ完成しました。ただし、現在のビューが変更されるたびにいくつかのインスタンス変数を保存し、ビューが再度開かれたときにそれらを再読み込みする必要があります。

intBOOLなどの基本的な C 型の変数を問題なくロードできますが、Objective-C オブジェクトで作成されたリンク リストには問題があります。

リンク リストは、3 つのポインター ( startPointercurrPointer、およびendPointer ) によってアクセスされるメモリで構成されます。各要素は、最後のポインター、次のポインター、ネストされたリンク リスト ( 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. lastElementおよびfirstElementメソッドを使用してリストを検索するよりも、 currPointerendPointer、およびstartPointerの間の関係を維持する効率的な方法はありますか?
  3. 私が提示した読み込みコードの背後にあるテクニックに何か問題がありますか? それがなければ、何の問題もありません。それで、私はまだBAD_ACCESSメッセージを受け取ります。これらのメッセージがローディング コードに関連しているかどうか、またはアプリケーションの残りの部分でオブジェクトの割り当てを処理した方法に関連しているかどうかを知りたいです。

前もって感謝します!

4

2 に答える 2

2

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

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

NSMutableArray を使用しない場合は、encodeWithCoder メッセージに応答するコンテナー クラスを作成し、その方法でリストをエンコードすることをお勧めします。ポインターを保存するのではなく、ポインターを使用してコンテナーを移動し、確定的な順序でアーカイブします。

于 2009-03-20T15:39:10.190 に答える
1

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

あなたは別の言語からObjective-Cに何かを押し込もうとしていますが、その結果はあなたがやりたいことに対して多くの仕事をしています。

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

于 2009-03-20T22:52:19.867 に答える