2012-05-10 33 views
5

Tôi có UITableView với một số nội dung được tải theo số không đồng bộ. Khi người dùng xoay thiết bị, tôi cần phải thực hiện [tableView reloadData] theo phương thức -willRotateToInterfaceOrientation. ReloadData hoạt động không đồng bộ trong trường hợp của tôi.Làm thế nào để làm cho MainThread chờ đợi cho đến khi một số hành động async được thực hiện?

Tôi hiểu rằng reloadData hoạt động trong chuỗi chính, nhưng nó kích hoạt cellForRowAtIndexPath, hoạt động không đồng bộ trong trường hợp của tôi.

Vì vậy, câu hỏi đặt ra là làm thế nào để chủ đề chính đợi cho đến khi UITableView's reloadData kết thúc.

Trả lời

2

Nếu bạn gọi reloadData từ willRotateToInterfaceOrientation thì nó được gọi trên chuỗi chính. Trong thực tế UIViews là không thread an toàn và chỉ nên được xử lý từ các chủ đề chính (trong trường hợp đối với một số lý do ai đó được ý tưởng để gọi reloadData từ thread khác).

Tôi nghĩ có sự nhầm lẫn liên quan đến "không đồng bộ" như một thuật ngữ. Gọi lại không đồng bộ cho các đại biểu giao diện người dùng như willRotateToInterfaceOrientation được gọi trên luồng chính. Để không đồng bộ không nhất thiết có nghĩa là một luồng khác (mặc dù chạy không đồng bộ "song song" thì không).

Tôi khuyên bạn nên đọc tài liệu của Apple dành cho NSRunLoop. Nó là một phần không thể thiếu trong cách các ứng dụng iOS chạy và là một phần mềm cần thiết cho các lập trình viên ứng dụng hiểu được.

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html

+0

Tôi hiểu rằng reloadData được gọi trong chuỗi chính. Nhưng realodData gọi cellForRowAtIndexPath ... và phương thức này cần tải một số dữ liệu không đồng bộ. –

+0

Tôi hiểu, vì vậy bạn không đợi tải lạiData để hoàn thành nhưng các tác vụ không đồng bộ tải lạiData sẽ ngừng hoạt động để hoàn thành. Bạn có thể sửa đổi câu hỏi của mình để phản ánh điều này không? NSRunLoop vẫn là những gì bạn muốn, mặc dù tôi không hiểu tại sao bạn muốn giữ cho bạn con tin chủ đề chính trong khi tải dữ liệu không đồng bộ. – NSProgrammer

+0

Một chủ đề chính cần phải chờ reloadData, bởi vì điều này sẽ làm cho hình ảnh động quay dễ chịu. –

3

Bạn có thể sử dụng CFRunLoopRun để làm cho chính chủ đề của bạn chờ đợi cho đến khi dữ liệu UITableView được nạp lại. Sau khi dữ liệu được tải lại, hãy gọi CFRunLoopStop kết quả truyền qua của CFRunLoopGetMain làm thông số.

+0

Cảm ơn, tôi thấy điều này không dễ đọc tài liệu. Tôi sẽ cố gắng hiểu. –

2

Bạn sẽ cần tải dữ liệu bảng của mình dưới nền, sau đó gọi phương thức tải lại của UITableView.

Bạn có thể sử dụng GCD để dễ dàng gửi hàm tải của bạn không đồng bộ lên hàng đợi nền. Khi công việc đó kết thúc, hãy gửi lại luồng công việc tới luồng chính mà một khối gọi là [tableView reloadData]. Dưới đây là cách thực hiện:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{ 

    ... 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_async(queue, ^{ 

    // load your table data here 
    [self loadMyTableData]; 

    // when done dispatch back to the main queue to load the table 
    dispatch_queue_t mainQueue = dispatch_get_main_queue(); 
    dispatch_async(mainQueue, ^{ 

     [self.tableView reloadData]; 
     }); 
    }); 
    ... 
} 
+0

Để đặt [tự tảiMyTableData]; tôi cần phải thay đổi một nửa mã để lưu trữ dữ liệu và hơn là đẩy nó vào uitableviewcells được phân lớp của tôi và nội dung của nó –

Các vấn đề liên quan