私は最近、私がマルチスレッドのアプローチのために発生していることを知っていた厄介なバグを追跡しています(私は最後に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;
}
}
私はそれを追加しました。面白いことは、上で述べたように、これはランダムに起こることです。 – Icky
まあ、私はこれを修正しましたが、どういうわけか違っています。私が知りたいのですが、なぜ@synchronized(articleArrays)が私にとってうまくいかなかったのですか?とにかく私はあなたのアプローチが正しいと思うので、私にそのように案内してくれてありがとう! – Icky