Gần đây tôi cũng có một vấn đề tương tự. Nhiều khả năng các bản cập nhật bị trì hoãn của bạn là những thứ bạn đang thực hiện trên giao diện người dùng. Và đây là vấn đề: bạn không chạy trong luồng chính của ứng dụng (còn được gọi là chuỗi giao diện người dùng). Vì vậy, bất cứ điều gì bạn thay đổi giao diện người dùng sẽ không thực sự được hiển thị cho đến khi ... nó cảm thấy như hiển thị, có xu hướng xảy ra với một vẽ lại được kích hoạt bởi một cái gì đó khác trong ứng dụng.
Những gì bạn phải làm là bên trong hàng đợi khối của bạn cập nhật đồ họa của bạn trong thread UI như thế này:
dispatch_async(dispatch_get_main_queue(), ^{
// Do GUI stuff.
});
Đôi khi khối của bạn có thể là lớn hay chỉ sử dụng mã mà trước đó đã chạy trên các chủ đề chính, vì vậy rất khó để di chuyển tất cả nó đến một nơi cụ thể để chạy nó trên hàng đợi chính. Đối với những tình huống này, xếp hàng làm mới buộc trong thread UI vào cuối khối của bạn:
dispatch_async(dispatch_get_main_queue(), ^{
[self.somewidget setNeedsDisplay];
[self.view setNeedsDisplay];
[self.dontforgetme setNeedsDisplay];
});
Liên quan đến bạn "ứng dụng chiếm thời gian phản ứng ngọt ngào của ứng dụng của tôi", có vẻ như hai người là bạn cố gắng sử dụng GDC để tránh chặn giao diện người dùng. Để đảm bảo lập trình rằng bạn không xảy ra hoạt động chuyên sâu CPU trong chuỗi giao diện người dùng và ngược lại, bạn chạy cập nhật GUI trong khối giao diện người dùng, tôi đã tự tạo các macro sau:
/// Stick this in code you want to assert if run on the main UI thread.
#define DONT_BLOCK_UI() \
NSAssert(![NSThread isMainThread], @"Don't block the UI thread please!")
/// Stick this in code you want to assert if run on a background thread.
#define BLOCK_UI() \
NSAssert([NSThread isMainThread], @"You aren't running in the UI thread!")
bạn có thể thấy bằng các bình luận, tôi có xu hướng sử dụng các macro này ở đầu các phương thức mà tôi muốn đảm bảo rằng tôi không sử dụng sai sót ở sai địa điểm. Tôi đã đặt những macro này và nhiều thứ ngẫu nhiên khác tại số https://github.com/gradha/ELHASO-iOS-snippets mà bạn có thể thấy hữu ích.
Nguồn
2011-08-08 20:25:46
Tại sao bạn mong đợi nhật ký của mình hiển thị ngay lập tức? "Hàng loạt mã" của bạn có thể mất vài giây để chạy, trì hoãn nhật ký bằng nhiều, bởi vì nó sẽ chỉ thực hiện sau khi phần còn lại của mã của bạn có. –
Đây là điều làm tôi bối rối. Đó là sau mỗi bit mã, và xuất hiện ngay lập tức trong khi mã mất vài giây để hiển thị kết quả trên màn hình. – Andrew
OK, vì vậy bạn đang nói rằng câu lệnh NSLog có văn bản hiển thị ngay lập tức trên bàn điều khiển, nhưng "bó mã" của bạn chứa trong đó các cập nhật giao diện người dùng khác không có hiệu lực trên màn hình ngay lập tức?Nếu đó là trường hợp, loại cập nhật giao diện người dùng là gì? Chúng được gửi đi không đồng bộ trên chủ đề chính? Có quá trình nào có thể bị chặn trong vòng lặp chính trên chuỗi chính sau khi khối này được gửi đi, có khả năng ngăn cập nhật giao diện người dùng không? –