2011-10-09 31 views
6

Tôi có chế độ xem với một số logic vẽ rất phức tạp (đó là chế độ xem bản đồ thu thập từ dữ liệu GIS). Làm bản vẽ này trên sợi chính sẽ khóa giao diện người dùng và làm cho ứng dụng không phản hồi. Tôi muốn di chuyển các bản vẽ đến một chủ đề nền với ví dụ một NSOperation.Vẽ trong chuỗi nền trên iOS

Cách tốt nhất để cấu trúc này là gì?

Tôi hiện đang vẽ ra một bộ nhớ tắt CGContext và sau đó chuyển đổi đó thành một CGImageRef mà tôi gửi đến xem để blit trên chủ đề chính. Thật không may, điều này sử dụng rất nhiều bộ nhớ và có vẻ như tăng tốc GPU không còn được sử dụng vì nó hơi chậm hơn một chút. Có cách nào để vẽ trực tiếp vào chế độ xem từ chuỗi nền không? Tôi biết rằng UIKit không phải là đa luồng an toàn nhưng có thể có một số cách để khóa chế độ xem trong khi tôi đang vẽ bản vẽ?

Trả lời

1

Tôi chưa bao giờ gặp phải tình huống như vậy trên iPhone nhưng trên Mac, tôi gặp sự cố tương tự một lần.

  1. Sử dụng CGLayer để ủy quyền hoạt động vẽ của ngữ cảnh ngoại tuyến.
  2. Thử thêm bộ đếm thời gian cho NSRunLoop hiện tại và vào khoảng thời gian theo thời gian thực thi các lệnh đồ họa của bạn. Nó sẽ giống như thế này ...

...

kRenderFPS 25.0 //This is Maximum value 

renderTimer = [[NSTimer timerWithTimeInterval:(1.0/(NSTimeInterval)kRenderFPS) target:viewobject selector:@selector(RenderUI:) userInfo:nil repeats:YES] retain]; 


[[NSRunLoop currentRunLoop] addTimer:renderTimer forMode:NSDefaultRunLoopMode]; 


[[NSRunLoop currentRunLoop] addTimer:renderTimer forMode:NSModalPanelRunLoopMode]; 


[[NSRunLoop currentRunLoop] addTimer:renderTimer forMode:NSEventTrackingRunLoopMode]; 

//In view class 
-(void)RenderUI:(id)param 
{ 
    [self setNeedsDisplayInRect:[self bounds]]; 
} 

này nên làm các trick.

Cũng thử lấy mẫu quy trình của bạn và kiểm tra xem ai đang tiêu thụ CPU. Điều này sẽ làm cho giao diện người dùng đáp ứng và rất nhanh.

Sự cố hiệu suất mà bạn đã đề cập có thể là do điều gì đó khác. Hãy thử quá trình lấy mẫu cpu. Nó sẽ cho bạn cái nhìn sâu sắc về ai đang thực sự lấy CPU.

+0

Bạn có nghĩa là CALayer? –

+1

No. CGLayer. http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/CGLayer/Reference/reference.html – MacGeek

+0

Vì vậy, tôi đang thử phương pháp này ngay bây giờ nhưng ngay cả khi tôi chạy với NSTimer và chỉ chạy 50% của thời gian (chạy trên khoảng 0,2 giây cho tối đa 0,1 cho mỗi chu kỳ vẽ) có vẻ như nó vẫn bỏ qua tất cả các sự kiện giao diện người dùng. Có lừa đảo gì ở đây không? –

6

Ngoài iOS 4.0, drawing is thread safe. Bạn có thể cần phải tự mình tạo một CGContext nhưng không có lý do gì bạn không thể vẽ trên một chuỗi nền.

Điều đó nói rằng, hầu hết các hoạt động của UIKit đều không có. Nếu bạn cần làm như vậy, bạn luôn có thể chuẩn bị trong một chủ đề nền và sau đó sử dụng performOnMainThread khi cần. Thậm chí còn có waitUntilDone. Điều đó nói rằng, bạn nên sử dụng NSOperationNSOperationQueue.

+1

Dường như có nhiều nhầm lẫn về điều này nhưng đây là câu trả lời đúng, như bản vẽ iOS 4.0 với UIKit là chuỗi an toàn. Đây là thông báo chính thức về điều này: http://developer.apple.com/library/ios/#releasenotes/General/WhatsNewIniPhoneOS/Articles/iPhoneOS4.html (tìm kiếm "thread"). –

+0

@Jon Tirsen, cảm ơn bạn đã giúp tôi giải thích câu trả lời. –

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