2013-09-23 40 views
8

我使用github的Project,它是一個圖像選擇器。 自ios7以來,我不得不做出一個非常小的改變,使您的相冊中的預覽圖像再次顯示,但是現在當您離開選擇器並重新進入時,所選照片(2/5)重置爲0/5即使我選擇了照片。我怎樣才能解決這個問題?線程問題在ios 7上的行爲不同

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0)似乎要永遠更新ui,即使使用dispatch_async(dispatch_get_main_queue()重新加載其中的ui。當我註釋掉dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0)時,圖片會立即加載,但其他事情會因爲隊列而中斷。

這裏是代碼片段與dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0)我的代碼改變我改變註釋掉

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

問題是什麼? –

+0

@Benoit我想知道如何更新選擇器,知道選擇了多少照片。它正確地做到了這一點,然後我刪除了調度,但需要刪除調度才能正確地在ios7中工作 – BluGeni

+0

我試過這個類,但即使在使用修補程序時它也不會顯示任何圖像。您可能想深入瞭解這裏的根本問題,您想要做的是解決方法,而不是正確的解決方法。 – lawicko

回答

0

我花了相當多的時間與此代碼和我找不到合適的解決方案。顯然,這個問題又拿出了GitHub上,並且用戶提供了一個修正:

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

但顯然他剛剛刪除在後臺運行的所有塊,所以我想,對於大量圖像的表現會壞。

我的預感是在dispatch_async塊中運行的代碼調用了一些UIKit函數 ,因此行爲基本上是未定義的。

例如,在我看來,中的setAsset函數在您發佈的dispatch_async中調用了AGIPGridItem.m。它調用UImage,儘管它在一個鎖內,但它仍應該在後臺線程上執行,而所有的UIKit代碼都應該在主線程上執行。

UITableViewCell load images and reused cells

但是即使我換一個dispatch_async(dispatch_get_main_queue()...)內通話它還沒有工作。

看來,在AGIPGridell.m通話[view removeFromSuperview];setItems負責莫名其妙,但刪除它創建內存泄漏(意料之中)的副作用。

0

全局調度隊列是一個共享資源。 DISPATCH_QUEUE_PRIORITY_LOW任務在隊列中的每個其他任務以較高優先級運行後運行。如果隊列中有很多優先級較高的塊,您的DISPATCH_QUEUE_PRIORITY_LOW任務可能無法運行很長時間!

這在Concurreny Programming Guide被證明還有libdispatch man pages

所以,基本上,其他更高優先級的任務是保持事物繁忙,你的低優先級任務沒有得到一個機會去。

+0

這並不能解釋爲什麼它可以在iOS6上正常工作。 – lawicko

+0

全局隊列是一個共享資源。應用程序或系統中的其他內容可能會在iOS 7中發生更改,可能會嘗試安排具有更高優先級的任務。例如,如果你有一個UIWebView,那可能是更高優先級的調度任務。 – quellish

6

AGIPCGridItemUIView的子類。 請勿在後臺線程上使用UIKit對象。

確保你需要後臺線程,如果你這樣做,只需要將繁重的任務放到後臺。創建一個UIView不應該是這種情況。

此外,不建議使用PRIORITY_LOW使用簡單的PRIORITY_DEFAULT

編輯:如果你是好奇爲什麼它沒有在iOS 6的工作:這是UIKit中的實現細節。它仍然是錯誤的,但不知怎的做了你的預期。

0

我突出顯示了iMartin的答案「AGIPCGridItem是UIView的子類,不能在後臺線程上使用UIKit對象。他明白了。

將iOS6移動到7時,我遇到了一個非常類似的問題。我在後臺線程中調度ALAssets請求。一旦獲取完成,我將構建UIImageView,一個UILabel和一個包裝器,然後將該對象發送到主/前景線程以進行渲染。這在iOS6上運行良好,但在7上它沒有畫20秒左右。它有時會在觸摸等UI事件之後繪製。

修復方法是在後臺獲取ALAsset,將其發送到創建圖像視圖的主線程等。現在就像魅力一樣。