0

sqlliteデータベースにいくつかのデータが保存されているiphoneアプリケーションを開発しています。ビューがロードされたら、データベースからバックグラウンドスレッドでデータをロードしたいと思います。問題は、アプリケーションがクラッシュし続けることであり、その理由がわかりません。

コード:

-(id) init
{
    if((self=[super init]))
    {
       [self performSelectorInBackground:@selector(loadList) withObject:nil];
    }
 }

-(void) loadList
{
   @autoreleasepool
   {
      Loader * loader = [[Loader alloc] init];
      NSMutableArray * array = [loader getItemList];
      [array retain];
      NSLog(@"Got %d items",[array count]);

      [self performSelectorOnMainThread:@selector(createList:) withObject:array waitUntilDone:false];
      [loader release];
   }
}

-(void) createList: (NSMutableArray*) array
{
    items = array;
    int i;
    Item * it;
    for(i = 0; i < [items count]; i++)
    {
      it = [items objectAtIndex: i];
      [it getName]; // crashes
      // populate the list
    } 
}

ローダーは、Itemオブジェクトを含むNSMutableArrayを返します。アイテムgetName(NSString *を返す)を呼び出すと、アプリケーションがクラッシュします。アイテム名のプロパティがリリースされているため、クラッシュすることがわかりました。私は何が間違っているのですか?

ありがとう!

4

3 に答える 3

1

この特定のバグは、通過しているwaitUntilDone:NOように見えるため、配列はすぐに解放され、その結果、そのアイテムも解放されます。

しかし、一般的に、UIKitはスレッドセーフではないため、これは簡単な設計にすぎません。私はおそらく、このようなもののロードを、ビュー内ではなく、タスクを処理する別のクラスに配置します。

于 2012-10-15T19:50:54.760 に答える
1

設定に使用しているオブジェクトのタイプに問題がある可能性がありますarray

紙に指で証明するものを見つけることができませんが、その目的を保持していると確信しperformSelectorOnMainThread:withObject:waitUntilDone:ています。ただし、の各アイテムがarrayへの参照をloader保持している場合は、そのオブジェクトを保持する責任を負う必要があります。手動でそれを存続させようとしているように見えますが、チャックがほのめかしているように、への呼び出しperformSelector...は即座に戻り、呼び出しが完了するのを待ちません。

于 2012-10-15T21:31:15.123 に答える
0

行にブレークポイントを設定します:

 it = [items objectAtIndex: i];

次に、次のように入力します

po it

デバッガーで、名前フィールドの内容を確認します。推測として、私は2つのことのいずれかを言います:1)getNameが返すフィールドがオブジェクトで初期化されていない(つまり、実際のNSString *ではない)か、SQLiteからC文字列を取得している(それが通常返すものです)そしてあなたはそれをNSString*として扱わせようとしています。後者の場合は、[myCStringstringWithUTF8String]を使用してC文字列をNSStringに変換できます*

于 2012-10-15T21:08:47.953 に答える