2011-11-17 21 views
5

Tôi đang cố gắng sử dụng sendAsynchronousRequest mới được thêm vào trong iOS5. Tôi có một lớp mô hình (File) với một phương thức yêu cầu một số dữ liệu từ một máy chủ, và sau đó chuyển dữ liệu này đến lớp điều khiển (FilesController) đã tạo ra đối tượng mô hình.sendAsynchronousRequest with tableView reloadData delay on draw

Lớp mô hình có một phương pháp với mã tiếp theo:

[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { 
    NSArray *decodedResponse = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; 
    NSArray *files = [self _dictionariesToFiles:decodedResponse]; 
    handler(files); 
}]; 

Lớp điều khiển, sử dụng nó như thế này:

[File findAll:conditions completionHandler:^(NSArray *files) { 
    dataSource = files; 

    NSLog(@"set"); 

    [self.tableView reloadData]; 

    NSLog(@"reload"); 

    activityIndicator.hidden = TRUE; 
}]; 

Trong giao diện điều khiển tôi có thể xem ngay lập tức như thế nào NSLogs cho thấy "đặt" và "tải lại" tin nhắn, nhưng bảng và chỉ báo không thay đổi cho đến khi một số giây (5-10 giây) đã trôi qua.

Ai đó biết vấn đề ở đâu?

Cảm ơn.

PD: Tôi đã thay đổi yêu cầu không đồng bộ bằng một đồng bộ tương thích, sau đó vấn đề sẽ biến mất nhưng muốn sử dụng yêu cầu không đồng bộ cho việc này.

Đây là mã đồng bộ tương thích:

NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 
NSArray *decodedResponse = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil]; 
NSArray *files = [self _dictionariesToFiles:decodedResponse]; 
handler(files); 

Trả lời

16

bạn cần làm [tableView reloadData] về các chủ đề chính. Tất cả các hoạt động UI phải được thực hiện trên luồng chính. Nhiều cách để làm điều này. Một là:

dispatch_async(dispatch_get_main_queue(), ^{ 
    [self.tableView reloadData]; 
    activityIndicator.hidden = TRUE; 
}); 

EDIT: thêm activityIndicator để dụ

3

tôi đã có một số vấn đề sử dụng: [[NSOperationQueue alloc] init] nhưng sử dụng [NSOperationQueue mainQueue] mọi thứ đều hoàn hảo. Sử dụng Hàng đợi mới, dòng thực hiện không tuân theo trình tự tự nhiên

+2

Đó là bởi vì mainQueue chạy trên luồng chính, nơi tất cả các công cụ giao diện người dùng đều phải xảy ra. – greenisus

+0

@Rscorreia greenisus là chính xác Tôi đã có cùng một vấn đề như bạn cho đến khi tôi phát hiện ra điều này. –

+0

@greenisus Vì vậy, làm thế nào để bạn nhận được một yêu cầu không đồng bộ để làm việc một cách nhanh chóng sau đó? Nếu bạn làm '' '[NSOperationQueue mainQueue]' '' nó đặt nó vào chủ đề chính mà đánh bại mục đích của việc sử dụng một yêu cầu không đồng bộ ngay từ đầu ....? – Supertecnoboff