2013-09-23 17 views
8

Tôi đang sử dụng Project này từ github, đây là bộ chọn hình ảnh. Tôi đã phải thực hiện một thay đổi rất nhỏ từ ios7 để làm cho hình ảnh xem trước từ album của bạn hiển thị lại nhưng với thay đổi đó ngay bây giờ khi bạn rời khỏi bộ chọn và quay lại vào ảnh đã chọn (2/5) đặt lại về 0/5 mặc dù tôi đã chọn ảnh. Làm thế nào tôi có thể sửa lỗi này?Sự cố phân luồng hoạt động khác nhau trên ios 7

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0) dường như mất vĩnh viễn để cập nhật ui ngay cả với dispatch_async(dispatch_get_main_queue() để tải lại ui bên trong của nó. Khi tôi nhận xét các hình ảnh dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0) tải ngay lập tức nhưng những thứ khác bị hỏng mà phụ thuộc vào hàng đợi.

đây là đoạn mã với dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0) tôi đã thay đổi với mã tôi đã thay đổi nhận xét ra

AGIPCAssetsController.m:

- (void)loadAssets 
{ 
    [self.assets removeAllObjects]; 

    __ag_weak AGIPCAssetsController *weakSelf = self; 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 

     __strong AGIPCAssetsController *strongSelf = weakSelf; 

     @autoreleasepool { 
      [strongSelf.assetsGroup enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { 

       if (result == nil) 
       { 
        return; 
       } 

       AGIPCGridItem *gridItem = [[AGIPCGridItem alloc] initWithImagePickerController:strongSelf.imagePickerController asset:result andDelegate:strongSelf]; 
       if (strongSelf.imagePickerController.selection != nil && 
        [strongSelf.imagePickerController.selection containsObject:result]) 
       { 
        gridItem.selected = YES; 
       } 
       [strongSelf.assets addObject:gridItem]; 
      }]; 
     } 

     dispatch_async(dispatch_get_main_queue(), ^{ 

      [strongSelf reloadData]; 

     }); 

    }); 
    [strongSelf reloadData]; 

} 
+0

Câu hỏi là gì? –

+0

@Benoit Tôi muốn biết cách cập nhật bộ chọn để biết số lượng ảnh được chọn. Nó đã làm điều này một cách chính xác trước khi tôi loại bỏ các công văn nhưng công văn cần phải được gỡ bỏ cho nó để làm việc trong ios7 một cách chính xác – BluGeni

+0

Tôi đã thử lớp đó nhưng nó không hiển thị cho tôi bất kỳ hình ảnh ngay cả khi tôi sử dụng sửa chữa của bạn. Bạn có thể muốn đào sâu hơn để xem vấn đề gốc ở đây là gì, những gì bạn đang cố gắng làm là một cách giải quyết, không phải là sửa chữa đúng đắn. – lawicko

Trả lời

0

tôi đã dành khá nhiều thời gian với mã này và tôi không thể tìm thấy một giải pháp thích hợp. Rõ ràng vấn đề này đã đưa ra trên github và người dùng được cung cấp một sửa chữa:

https://github.com/arturgrigor/AGImagePickerController/issues/19

Nhưng dường như anh chỉ cần loại bỏ tất cả các khối chạy ở chế độ nền, vì vậy tôi nghĩ rằng đối với một số lượng lớn các hình ảnh hiệu suất sẽ xấu.

Linh cảm của tôi là bên trong khối dispatch_async chạy mã gọi một số hàm UIKit, và do đó hành vi về cơ bản là không xác định.

Ví dụ: dường như với tôi rằng hàm setAsset trong AGIPGridItem.m được gọi bên trong dispatch_async mà bạn đã đăng. Nó đang gọi UImage, và mặc dù nó nằm bên trong một khóa, nó vẫn phải được thực hiện trên luồng nền, trong khi tất cả mã UIKit phải được thực hiện trên chính.

UITableViewCell load images and reused cells

Nhưng ngay cả khi tôi quấn gọi bên trong một dispatch_async(dispatch_get_main_queue()...) nó không hoạt động được nêu ra.

Dường như cuộc gọi [view removeFromSuperview]; trong setItems trong AGIPGridell.m chịu trách nhiệm bằng cách nào đó, nhưng loại bỏ nó có tác dụng phụ của việc tạo ra một sự rò rỉ bộ nhớ (gì ngạc nhiên).

0

Hàng đợi công văn toàn cầu là tài nguyên được chia sẻ. DISPATCH_QUEUE_PRIORITY_LOW tác vụ chạy sau mỗi tác vụ khác trong hàng đợi ở mức ưu tiên cao hơn đã chạy. Nếu hàng đợi nhận được nhiều khối được gửi với mức độ ưu tiên cao hơn, nhiệm vụ DISPATCH_QUEUE_PRIORITY_LOW của bạn có thể không chạy trong một thời gian rất dài!

này được diễn tả trong Concurreny Programming Guide cũng như libdispatch man pages

Vì vậy, về cơ bản, nhiệm vụ ưu tiên cao hơn khác được giữ mọi thứ bận rộn và nhiệm vụ ưu tiên thấp bạn không nhận được một cơ hội để đi.

+0

Điều này không giải thích tại sao nó hoạt động tốt trên iOS6. – lawicko

+0

Hàng đợi chung là tài nguyên được chia sẻ. Một cái gì đó khác trong ứng dụng của bạn hoặc trong hệ thống có thể đã thay đổi trong iOS 7, có thể đang cố lên lịch các tác vụ trong đó có mức độ ưu tiên cao hơn. Ví dụ, nếu bạn có một UIWebView, đó có thể là các nhiệm vụ lên lịch ở mức ưu tiên cao hơn. – quellish

6

AGIPCGridItem là phân lớp của UIView. Không làm việc với các đối tượng UIKit trên chủ đề nền.

Đảm bảo bạn cần chuỗi nền và nếu bạn làm như vậy, chỉ đặt các tác vụ nặng vào nền. Tạo ra một UIView không nên là trường hợp đó.

Ngoài ra, không nên sử dụng PRIORITY_LOW sử dụng đơn giản PRIORITY_DEFAULT.

Chỉnh sửa: Nếu bạn tò mò lý do tại sao nó đã hoạt động trên iOS 6: Đó là chi tiết triển khai của UIKit. Nó vẫn là sai, nhưng bằng cách nào đó đã làm những gì bạn mong đợi.

0

Tôi đánh dấu câu trả lời của iMartin "AGIPCGridItem là phân lớp của UIView. Không hoạt động với các đối tượng UIKit trên chuỗi nền". Anh ta hiểu rồi.

Tôi gặp sự cố tương tự khi di chuyển iOS6 đến 7. Tôi đã gửi yêu cầu ALAssets trong chuỗi nền. Sau khi tìm nạp xong, tôi sẽ xây dựng UIImageView, một UILabel, và một trình bao bọc và sau đó gửi đối tượng này tới luồng chính/nền trước được hiển thị. Điều này làm việc tốt trên iOS6, nhưng trên 7 nó đã không rút ra trong khoảng 20 giây. Nó đôi khi sẽ vẽ sau một sự kiện giao diện người dùng như một liên lạc.

Khắc phục là tìm nạp ALAsset trong nền, gửi đến chuỗi chính nơi tôi đã tạo chế độ xem hình ảnh, v.v. Hoạt động như một nét duyên dáng ngay bây giờ.

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