JSONからデータを取得し、解析してUITableViewに入力するアプリにviewControllerがあります。データの取得中にアプリがハングしないように、スレッドを使用してデータをロードしています。
問題:
numberOfRowsInSection が 0 を返し、アプリの起動時に UITableView が読み込まれないことがあります。時々、すべてがうまくいきます。それはすべてランダムです:S
考えられる説明:
問題は、データが取得される前に numberOfRowsInSection が呼び出されることがあるようです。numberOfRowsInSection は、「subjects」と呼ばれる NSMutableArray のカウントの値を返します。loadData が呼び出されると、「subjects」内のオブジェクトが追加されます。そのため、numberOfRowsInSection は「件名」の数を返す必要があり、「件名」が入力された後に呼び出すべきではありません。
アプリを起動すると、「件名」が入力された後に numberOfRowsInSection が呼び出され、UITableView にデータが表示されることがありますが、アプリを起動すると、「件名」が入力される前に numberOfRowsInSection が呼び出され、UITableView にデータが表示されないことがあります。
コード: これが私のコードです:
-(void)loadData:(id)sender
{
dispatch_queue_t getRemindersQueue=dispatch_queue_create("reminders JSON downloader with reload Button", NULL);
dispatch_async(getRemindersQueue, ^{
[self getReminders];
dispatch_async(dispatch_get_main_queue(), ^{
self.navigationItem.rightBarButtonItem=sender;
[self.tableView reloadData];
});
});
dispatch_release(getRemindersQueue);
}
-(void)getReminders
{
NSURL * aURL = [NSURL URLWithString: @"http://www.merrycode.com/apps/IELTS/RemindersJSON"];
NSURLRequest *request = [NSURLRequest requestWithURL:aURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0];
NSError *responseError=nil;
// Perform request and get JSON back as a NSData object
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&responseError];
if(responseError)
{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *parsingError = [[UIAlertView alloc] initWithTitle:@"Network Error"
message:@"Can not reach the servers. Make sure you are connected to the internet."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[parsingError show];
});
return;
}
NSString *str = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSLog(@" String of Reminders JSON: %@",str);
NSString *newStr= [self stringByRemovingControlCharacters:str];
response = [newStr dataUsingEncoding:NSUTF8StringEncoding];
NSError *jsonParsingError = nil;
NSArray *publicTimeline = [NSJSONSerialization JSONObjectWithData:response options:0 error:&jsonParsingError];
NSLog(@"%@", jsonParsingError);
NSLog(@" publicTimeline Array Count: %d", [publicTimeline count]);
if([publicTimeline count] == 0)
{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *parsingError = [[UIAlertView alloc] initWithTitle:@"Error Retriving Data"
message:@"There was an error reciving data from the server."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[parsingError show];
});
return;
}
NSDictionary *colleges;
for(int i=0; i<[publicTimeline count];i++)
{
colleges= [publicTimeline objectAtIndex:i];
NSLog(@"Reminders: %@", [colleges objectForKey:@"title"]);
[self.subjects addObject:[colleges objectForKey:@"title"]];
[self.dates addObject:[colleges objectForKey:@"date"]];
[self.description addObject:[colleges objectForKey:@"desc"]];
}
[self.subjectsInNSUserDefaults removeAllObjects];
[self.datesInNSUserDefaults removeAllObjects];
[self.descriptionInNSUserDefaults removeAllObjects];
[self.userDefaults setObject:self.subjects forKey:@"SUBJECTS"];
[self.userDefaults setObject:self.dates forKey:@"DATES"];
[self.userDefaults setObject:self.description forKey:@"DESCRIPTION"];
[self.userDefaults synchronize];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(@"Array Count in numberOfRowsInSection: %d",[self.subjects count]);
return [self.subjects count];
}