2012-03-17 11 views
2

私はTBXML + HTTPを使用してWebサイトからXMLデータを取得しています。私がしたいことは、処理されたデータをUITableViewに取り込むことです。 すべてのエントリを保持するNSMutableArrayを作成しましたが、それまではすべて正常に動作しています。 問題は、サーバからデータを正常に取得して配列に格納した後に、reloadDataを使用してデータを表示するようにテーブルを更新しようとするときです。UITableView reloadDataに時間がかかりすぎた

20行のテーブルを作成するのに約5秒かかります。奇妙な部分は、フェッチが本当に速く起こっているので、データはすぐに利用できるということです。私は何がそんなに長くかかるのか分かりません。ここでは、ログからいくつかの情報です:あなたが見ることができるように

2012-03-17 18:46:01.045 MakeMyApp[4571:207] numberOfSectionsInTableView: 1 
2012-03-17 18:46:01.047 MakeMyApp[4571:207] numberOfRowsInSection: 0 
2012-03-17 18:46:01.244 MakeMyApp[4571:1f03] numberOfSectionsInTableView: 1 
2012-03-17 18:46:01.245 MakeMyApp[4571:1f03] numberOfRowsInSection: 20 
2012-03-17 18:46:01.245 MakeMyApp[4571:1f03] Ok, I'm done. 20 objects in the array. 
2012-03-17 18:46:01.246 MakeMyApp[4571:1f03] Finished XML processing. 
2012-03-17 18:46:06.197 MakeMyApp[4571:1f03] cellForRowAtIndexPath: 

が、それはペアnumberOfSectionsInTableView:/numberOfRowsInSection: 2回発射:最初は、ときのビューのロード私はあなたが[self.tableView reloadData];

を行う際に、第二があります1秒未満で、配列に20個のオブジェクトが取り込まれ、XMLが処理されるすべての作業が完了していることがわかります。 cellForRowAtIndexPath:は5秒後にどのように起動されますか?ここで

は、問題を見つけるのに役立つかもしれないコードの一部です:

- (void)createRequestFromXMLElement:(TBXMLElement *)element { 
    // Let's extract all the information of the request 
    int requestId = [[TBXML valueOfAttributeNamed:@"i" forElement:element] intValue]; 

    TBXMLElement *descriptionElement = [TBXML childElementNamed:@"d" parentElement:element]; 
    NSString *description = [TBXML textForElement:descriptionElement]; 

    TBXMLElement *statusElement = [TBXML childElementNamed:@"s" parentElement:element]; 
    int status = [[TBXML textForElement:statusElement] intValue]; 

    TBXMLElement *votesCountElement = [TBXML childElementNamed:@"v" parentElement:element]; 
    int votesCount = [[TBXML textForElement:votesCountElement] intValue];  

    // Creating the Request custom object 
    Request *request = [[Request alloc] init]; 

    request.requestId = requestId; 
    request.description = description; 
    request.status = status; 
    request.votes_count = votesCount; 

    [requestsArray addObject:request]; 
} 


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

    appListCell *cell = (appListCell *)[tableView dequeueReusableCellWithIdentifier:@"appListCell"]; 

    Request *request = [requestsArray objectAtIndex:indexPath.row]; 

    cell.appIdLabel.text = [NSString stringWithFormat:@"#%d", request.requestId]; 
    cell.appTextLabel.text = request.description; 
    cell.appVotesLabel.text = [NSString stringWithFormat:@"%d votes", request.votes_count]; 

    return cell; 
} 

どうもありがとう!

EDIT:

- (void)traverseXMLAppRequests:(TBXMLElement *)element { 
    int requestCount = 0; 
    TBXMLElement *requestElement = element->firstChild; 

    // Do we have elements inside <re>? 
    if ((requestElement = (element->firstChild))) { 
     while (requestElement) { 
      [self createRequestFromXMLElement:requestElement]; 

      requestCount++; 

      requestElement = [TBXML nextSiblingNamed:@"r" searchFromElement:requestElement]; 
     } 
    } 

    [self.tableView reloadData]; 

    NSLog(@"Ok, I'm done. %d objects in the array.", [requestsArray count]); 

} 

EDIT 2:私の代わりに20の、ちょうど1行の情報をフェッチしようとした、遅延が全く同じです。

+0

私は興味深い発見だあなたがcellForRowAtIndexPathのためのNSLogを取得しているということです:呼び出していますが、そこに任意のNSLogsを持っていません。あなたのコードをクリーンアップしましたか、実際にどこか別の場所にコールしていますか? – RonLugge

+0

申し訳ありませんが、私はそれをより明確にするべきです。私は自分のコードをきれいにしました。なぜなら、たくさんのことをすでに試みていて、そのコードはNSLogsや他のトリックの混乱であるからです。 – user1276108

+0

おそらく、 'reloadData'呼び出しを含むメソッドのコードも表示する必要があります。 – jonkroll

答えて

0

はどこん:

- (void)createRequestFromXMLElement:(TBXMLElement *)element 

が呼び出されますか?そのファイルの内容を取得するための20のWebリクエストを作成しているようなサウンドです。そうすれば、XMLファイル全体を取得してローカルに解析するという1つの要求を行うのではなく、物事を遅くすることになります。

VCコード全体を投稿できますか?

16

私はこれが実際にはという古い質問だと知っていますが、まったく同じ問題を抱えて、原因を知っていると思います。この同じ質問につきまとう人を助けるかもしれません...

あなたのreloadDataコールは、メインスレッドではなくバックグラウンドスレッドで起こっていると思われます。あなたが描写したのはこれの正確な効果です。コードは実行されますが、ユーザーインターフェイスの更新には長い遅延(5〜10秒)があります。

reloadDataコールを変更してみてください:メインスレッド上であなたtableViewのデータを再ロードすることを確認してくださいあなたはmainThread

以外のスレッドでreloadDataを呼び出している

dispatch_async(dispatch_get_main_queue(), ^{ 
    [self.tableView reloadData]; 
}); 
+0

ありがとうございました...それは多くの助けとなりました – GJain

4

以下のように:

OBJ-C:

[self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO]; 

スウィフト3:

DispatchQueue.main.async { 
    self.tableView.reloadData() 
} 
+1

これは正しい解決策です。 – Brave

+0

これは正しい解決策であり、迅速かつ細かい作業(Y) – Mubashar

関連する問題