UITabBarControllerを使用してビューを切り替えるアプリケーションを作成しています。 1つのタブは、UITableViewにデータを入力する前にJSONデータを収集して処理するWebリクエストを作成します。このデータをバックグラウンドで読み込もうとしているので、ユーザーがタブを押したときにテーブルの表示が遅れることはありません。 ActivityIndicatorが表示され、テーブルにデータがロードされます。UITabViewControllerでdispatch_syncを使用してデータを取得する
各リクエストが作成され、処理され、結果がNSMutableArrayに格納され、その後、ソートされてUITableViewに追加されます。
dispatch_syncを使用すると、データがロードされ、配列が作成されて正常に表示されますが、ビューのUIの読み込みがブロックされます。私は何らかの理由でこのクエリーをバックグラウンドキューに取得していないので、考えています。 dispatch_asyncを使用すると、メインスレッドのNSMutableArrayにアクセスしようとすると例外が発生します。
私の質問は、このTableViewを含むタブに切り替え、データがロードされ、バックグラウンドで処理され、一度完了した後、ActivityIndicatorを提示するための適切なパターンは何ですか。処理されたデータがロードされる。 UITableViewControllerから
のrelaventコード:
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
- (void)viewDidLoad
{
[super viewDidLoad];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
currentLat = appDelegate.currentLatitude;
currentLong = appDelegate.currentLongitude;
finalDistanceArray = [[NSMutableArray alloc] init];
[self compareLocationMMC];
[self compareLocationLVMC];
[self compareLocationSBCH];
[self compareLocationGVCH];
[self compareLocationSYVCH];
NSSortDescriptor *lowestToHighest = [NSSortDescriptor sortDescriptorWithKey:@"distance" ascending:YES];
[hospitalList sortUsingDescriptors:[NSArray arrayWithObject:lowestToHighest]];
}
- (void)compareLocationMMC {
NSString * searchURL = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/directions/json?origin=%f,%f&destination=%f,%f&sensor=true", currentLat.floatValue, currentLong.floatValue, MMC_LAT, MMC_LON];
NSURL * myURL = [NSURL URLWithString:searchURL];
dispatch_sync(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:
myURL];
[self performSelectorOnMainThread:@selector(fetchedData:)
withObject:data waitUntilDone:YES];
});
}
//The compareLocationXXX method is repeated 4 more times with different search strings
- (void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
NSArray* stationDistance = [json objectForKey:@"routes"];
NSDictionary* legs = [stationDistance objectAtIndex:0];
NSArray* legsBetween = [legs objectForKey:@"legs"];
NSDictionary* distanceBetween = [legsBetween objectAtIndex:0];
finalDistance = [distanceBetween valueForKeyPath:@"distance.text"];
[finalDistanceArray addObject:finalDistance];
}
ありがとうございます!私は、バックグラウンドでこれは正常に動作していると思いますが、後続のコードはNSMutableArrayにアクセスして、データがロードされる前に例外を起こしています。データにアクセスする前にデータがロードされ、ソートされていることを確認するにはどうすればよいでしょうか? – blueHula
「ここで背景を使用する」の部分が表示されるまで、読み込んだデータを使用しないでください。これはおそらくあなたのフェッチされたデータをコピーして 'reloadTable'を呼び出すでしょう[私が投稿したこの回答は新しい問題と関連しています。](http://stackoverflow.com/a/8962406/927947) – NJones