2011-01-19 9 views
1

私は最近、私がマルチスレッドのアプローチのために発生していることを知っていた厄介なバグを追跡しています(私は最後にcrashreportを追加します)。iPhone - Tableviewでのマルチスレッド - 実現可能なアプローチ?

私のアプリケーションでは、UITableViewを読み込み、Coredataを使用してデータを格納します。このデータは順番にWebサービスから取得されるため、接続に応じて時間がかかることがあります。

とにかく、私はそれを少し追跡することができました、そして、私はそれがあってはならないと思ったが、配列が空であるために問題があることを知っている。それでは、

numberOfRowsInSection:(NSInteger)section 

と呼ばれますが、ときどきしかプログラムがクラッシュしません。

は、私がこれを適切にデバッグする方法思っていたし、私のアプローチは、ビューのロードが完了した後にtableViewに

reloadData 

を呼び出すことでした。しかし、明らかに

もちろん、これは役に立たなかった。ここで別のスレッドを作成し、データが準備され準備されているかどうかを繰り返し確認する正しい方法はありますか?どんな提案/意見?

2011-01-19 21:50:49.605 myApp[2017:307] *** Terminating app due to uncaught exception   
'NSRangeException', reason: '*** -[NSMutableArray objectAtIndex:]: index 0 beyond bounds for empty array' 
*** Call stack at first throw: 
(
0 CoreFoundation      0x314d0987 __exceptionPreprocess + 114 
1 libobjc.A.dylib      0x319a149d objc_exception_throw + 24 
2 CoreFoundation      0x31462795 -[__NSArrayM objectAtIndex:] + 184 
3 myApp         0x000092f7 -[MyTableViewController tableView:numberOfRowsInSection:] + 106 
4 UIKit        0x33902bcf -[UISectionRowData refreshWithSection:tableView:tableViewRowData:] + 1338 
5 UIKit        0x33903529 -[UITableViewRowData(UITableViewRowDataPrivate) _ensureSectionOffsetIsValidForSection:] + 120 
6 UIKit        0x33902645 -[UITableViewRowData numberOfRows] + 96 
7 UIKit        0x3390207b -[UITableView noteNumberOfRowsChanged] + 82 
8 UIKit        0x33901bff -[UITableView reloadData] + 582 
9 UIKit        0x33904a0b -[UITableView _reloadDataIfNeeded] + 50 
10 UIKit        0x33904e63 -[UITableView layoutSubviews] + 18 
11 UIKit        0x338b10cf -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 26 
12 CoreFoundation      0x3146ebbf -[NSObject(NSObject) performSelector:withObject:] + 22 
13 QuartzCore       0x30a6c685 -[CALayer layoutSublayers] + 120 
14 QuartzCore       0x30a6c43d CALayerLayoutIfNeeded + 184 
15 QuartzCore       0x30a6656d _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 212 
16 QuartzCore       0x30a66383 _ZN2CA11Transaction6commitEv + 190 
17 QuartzCore       0x30a70e4f _ZN2CA11Transaction5flushEv + 46 
18 QuartzCore       0x30a6db75 +[CATransaction flush] + 24 
19 UIKit        0x338e803f -[UIApplication _reportAppLaunchFinished] + 30 
20 UIKit        0x338d6317 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 462 
21 UIKit        0x338a248b -[UIApplication handleEvent:withNewEvent:] + 1114 
22 UIKit        0x338a1ec9 -[UIApplication sendEvent:] + 44 
23 UIKit        0x338a1907 _UIApplicationHandleEvent + 5090 
24 GraphicsServices     0x35d66f03 PurpleEventCallback + 666 
25 CoreFoundation      0x314656ff __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 26 
26 CoreFoundation      0x314656c3 __CFRunLoopDoSource1 + 166 
27 CoreFoundation      0x31457f7d __CFRunLoopRun + 520 
28 CoreFoundation      0x31457c87 CFRunLoopRunSpecific + 230 
29 CoreFoundation      0x31457b8f CFRunLoopRunInMode + 58 
30 UIKit        0x338d5309 -[UIApplication _run] + 380 
31 UIKit        0x338d2e93 UIApplicationMain + 670 
32 myApp        0x000029bf main + 70 
33 myApp        0x00002974 start + 40 
) 
terminate called after throwing an instance of 'NSException' 

numberOfRowsのようになります。あなたがダウンロードを行い、より正確にイベントコールバックは、リロードデータを呼び出す唯一の場所である必要があり、あなたのプロセスは、ここで説明するものから

- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section { 
// Return the number of rows in the section. 
NSLog(@"number of rows in section"); 
if (section == mySection) { 

    return [[articleArrays objectAtIndex:section] count]; 

} else { 
    return 0; 
} 

}

答えて

1

。新しいデータをテーブルのdataSetに追加した後に呼び出します。

numberOfRowsInSectionで0を返してもクラッシュは発生しませんが、カウントが0のときにネストした配列を取得しようとするとクラッシュします。 numberOfRowsInSection方法を投稿してください。

EDIT:そのオブジェクト数をやろうとしながら、バックグラウンドスレッドが配列を変異されるよう

サウンド/ルックス。

user210504というのは、配列を同期するとこれを止める可能性が高いということです。

通常、書き込みを同期するため、バックグラウンドスレッドが突然変異している場合は、numberOfRowsInSectionがカウントされなくなります。たとえば、

-(void)downloadFinished{ 

NSMutableArray * array = [[NSArray alloc] init];//t 
id * obj;//obj is your row data object. 

@synchronized(ar) 
{ 
    [array addObject:obj];//ar is your dataSet 
} 

[array release]; 
} 
+0

私はそれを追加しました。面白いことは、上で述べたように、これはランダムに起こることです。 – Icky

+0

まあ、私はこれを修正しましたが、どういうわけか違っています。私が知りたいのですが、なぜ@synchronized(articleArrays)が私にとってうまくいかなかったのですか?とにかく私はあなたのアプローチが正しいと思うので、私にそのように案内してくれてありがとう! – Icky

0

あなたができることの1つは、@ synchronizedブロックの可変配列へのアクセスをカプセル化することです。この方法で、データ構造の途中までアクセスしていないことを確認できます。そして、ルークが今述べたことにも同意します。

+0

最初の部分をもう少し詳しく説明できますか? – Icky

+0

またはブロックを緩める可能性があります –

関連する問題