ビューを切り替えるために UITabBarController を利用するアプリを書いています。1 つのタブは、UITableView に入力する前に、JSON データを収集して処理するための Web 要求を行います。このデータをバックグラウンドで読み込もうとしているので、ユーザーがタブを押してもテーブルの表示に遅延はありません。ActivityIndicator が表示され、テーブルにデータがロードされます。
各リクエストが行われ、処理され、結果が NSMutableArray に配置されます。これは並べ替えられ、UITableView に追加されます。
dispatch_sync を使用すると、データが読み込まれ、配列が作成されて正常に表示されますが、ビューの UI の読み込みがブロックされます。何らかの理由でこのクエリをバックグラウンド キューに取得していないため、考えています。dispatch_async を使用すると、メイン スレッドで NSMutableArray にアクセスしようとすると例外が発生します。
したがって、私の質問は、ユーザーがこの TableView を含むタブに切り替え、データの読み込みと処理中に (バックグラウンドで) ActivityIndicator を提示し、完了すると UITableView が処理された状態で読み込まれるようにするための適切なパターンは何ですか?データ。
UITableViewController からの関連コード:
#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];
}