2010-07-13 9 views
6

Tôi đang tải xuống hình ảnh trong ô xem bảng khi chúng cuộn lên màn hình. Vì lý do UX, tôi bắt đầu tải xuống hình ảnh trong - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath. Tôi không đợi cho đến khi chế độ xem bảng được cuộn xong. Khi đặt ô xem bảng, tôi bắt đầu tải xuống hình ảnh mà tôi chưa có. Tuy nhiên, chúng dường như không tải xuống đầy đủ cho đến khi chế độ xem bảng ngừng di chuyển. Ngay khi nó ngừng di chuyển, hình ảnh gần như tải xuống ngay lập tức.NSURLConnection có chặn chủ đề chính/giao diện người dùng

Có cách nào để sử dụng NSURLConnection nơi không bị chặn bởi chuỗi giao diện người dùng chính không? Hoặc, có cách nào mà những hình ảnh này sẽ tải xuống rất nhanh trong khi chế độ xem bảng đang được cuộn.

** EDIT **

Để chứng minh rằng NSURLConnection là chậm hơn tôi sử dụng NSThread tách một bộ chọn mới trong một chủ đề khác nhau. Sau đó tôi tải xuống dữ liệu và gọi lại chủ đề chính nơi tôi tạo UIImage và hiển thị nó trong chế độ xem bảng. Phương thức này hoạt động nhanh hơn.

Cá nhân, tôi nghĩ rằng NSURLConnection đang bị ném vào vòng lặp sự kiện nơi cuộn UITableView đang chặn nó.

+0

Người dùng có thể cuộn bảng nhanh hơn nhiều so với điện thoại có thể nhấn vào mạng và tải xuống hình ảnh. Nghe có vẻ bình thường với tôi ... – psychotik

+0

Tôi vừa mới thực hiện giải pháp tương tự của mình bằng cách tách một NSThread mới và tải xuống MUCH nhanh hơn. – rickharrison

+1

Chắc chắn tải xuống sẽ sử dụng vòng lặp sự kiện. Nghe có vẻ hợp lý rằng việc di chuyển bằng cách nào đó đã tắt nó đi. – JeremyP

Trả lời

-1

Có vẻ như bạn đang tải xuống đồng bộ.

http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html#//apple_ref/doc/uid/20001836-170129

đọc ở đó, và chắc chắn rằng bạn đang sử dụng các API async

+0

Tôi chắc chắn không sử dụng API đồng bộ. Tôi nghĩ rằng NSURLConnection bị ném vào vòng lặp sự kiện và UITableView sẽ chiếm tất cả thời gian trong vòng lặp đó. – rickharrison

2

Tôi đã có kinh nghiệm vấn đề này trước đây. Các phương thức ủy nhiệm không đồng bộ của NSURLConnection không kích hoạt trong khi scrollView đang được cuộn. Mặc dù quá trình tải xuống hoạt động ở chế độ nền nhưng luồng chính của bạn không được thông báo về các hình ảnh mới. Cũng giống như bạn, tôi tin rằng vấn đề có liên quan đến scrollviews được cuộn trong một NSRunLoop bên trong với một RunLoopMode khác nhau. Tôi đã nói chuyện với nhân viên Apple về việc này và yêu cầu họ xem mã của tôi, nhưng chúng tôi không thể tìm ra giải pháp.

Mặt khác, Jeff LaMarche có this post trên blog của anh ấy, nơi anh ấy làm điều tương tự và hoạt động như mong đợi. Tôi đã không thể tìm ra những gì anh ta làm khác nhau (chủ yếu là do không có thời gian), nhưng điều này có thể đáng xem.

1

Nếu bạn muốn "thực hiện NSURLConnection trên chuỗi chính không?", Thì có, tôi tin là vậy. Kết nối được mở và các phương thức ủy nhiệm được thực hiện trên luồng chính. Tôi chưa tìm thấy bất kỳ tài liệu nào để đề xuất khác và bạn có thể xác minh bằng cách gỡ lỗi.

Tôi nghĩ giả sử rằng cuộn UITableView chặn các cuộc gọi lại NSURLConnection trong vòng lặp chạy chính là chính xác.

Bạn đã đăng một giải pháp, tạo ra một chuỗi cho bộ chọn của bạn. Một lựa chọn khác sẽ được thực hiện tải của bạn như NSOperations, trong đó có một vài lợi ích:

  • Nếu bạn buộc các hoạt động để chạy đồng thời (xem Dave Dribin's excellent post on this), bạn có thể hạn chế số lượng tải đồng thời, mà có thể được mong muốn nếu bạn có một số lượng lớn hình ảnh trong bảng của mình. Bạn nói rằng tải xuống của bạn xảy ra "gần như ngay lập tức", nhưng điều đó có thể không phải là trường hợp nếu người dùng của bạn đang kết nối chậm và bảng của bạn chứa rất nhiều hình ảnh.
  • Bạn có thể hủy tất cả các thao tác nếu người dùng thực hiện điều gì đó khiến cho hình ảnh tải xuống không liên quan, như thực hiện một tìm kiếm khác.

Cách tiếp cận của Dave Dribin, mà tôi sử dụng, buộc các kết nối thực hiện lại trên sợi chính, nhưng điều đó có thể không cần thiết cho mục đích của bạn - bạn có thể sử dụng cách tiếp cận hiện tại của bạn gọi lại chủ đề chính sau khi tải xuống hình ảnh của bạn.

22

đọc NSDefaultRunLoopMode vs NSRunLoopCommonModes cho một lời giải thích tốt về lý do tại sao tất cả các thông báo tải xuống đại biểu được xếp hàng, nhưng để tải về trong khi di chuyển khi sử dụng sự thay đổi chính chủ đề từ này:

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request 
                   delegate:self]; 

này:

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request 
                   delegate:self 
                 startImmediately:NO]; 
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] 
         forMode:NSRunLoopCommonModes]; 
[connection start]; 
+0

Tuyệt vời, cảm ơn bạn. – Sam