0

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];
}
4

2 に答える 2

0

いくつかのアイデア...

あなたはこれがUIViewControllerであると言った(UITableViewControllerとは対照的に)。UITableView とデリゲートをどのように設定していますか? このバックグラウンド スレッドの実行中にまだ UITableView またはそのデリゲートを設定している場合、理論的には、UITableView の設定が完了する前にバックグラウンド スレッドが完了する可能性があり、奇妙な問題が発生する可能性があります (そして、これが「ランダムに発生する理由」を説明します) 」)。

また、UITableView にデータが取り込まれていない場合 (および他の何らかの応答がない場合、またはまったく応答がない場合) に、応答オブジェクトに大学に関する情報が取り込まれていることを確認しましたか? 応答エラーをチェックしている場所はわかりますが、エラーがなければ、大学に関する情報を含む応答になると想定しているようです (これは安全な仮定である場合とそうでない場合があります)。

于 2012-06-25T16:23:27.283 に答える
0

データの取得が問題であるとあなたが正しければ、私もこの問題を抱えています。私の洗練されていない解決策は、データがロードされることがわかっているときにテーブルにデータを入力するようにタイマーを設定することでした。

于 2012-06-25T16:25:47.447 に答える