2016-08-16 45 views
0

我想通過照片文件夾中的圖像計算總存儲量。我寫了如下代碼。我能夠成功抓取的圖像,但這段代碼有兩個問題 -ios - 計算照片文件夾中的總圖像大小

  1. 如果照片有超過7000的圖像,有時應用得崩潰。從,我知道它的內存問題。

  2. 如果我多次運行此代碼,請在6-7次應用程序崩潰後來回運行。

任何想法都會非常有幫助。我需要的視頻和歌曲來計算單獨

-(void)getPhotoSize{ 

    dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     [_allPhotos enumerateObjectsUsingBlock:^(PHAsset *asset, NSUInteger idx, BOOL *stop) { 
      if (idx<_allPhotos.count&&asset) { 

       [[PHImageManager defaultManager] requestImageDataForAsset:asset options:nil resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) { 
        float imageSize = imageData.length; 
        imageSize = imageSize; 
        data.totalPictureSize+=imageSize; 
         _currentPhotoAsset=asset; 
       }]; 
      } 
     }]; 
    }); 
} 
+0

您是否嘗試使用樂器運行來查看耗費內存的內容? –

+0

是的,當我來回走時,我跑了回憶檢查泄漏。但無法找到確切的點 – Shohrab

回答

0

存儲我不明白你在調度的代碼,而不是僅僅運行它,所以我要刪除GCD部分從下面的示例。您還需要運行儀器來檢查泄漏情況並找出消耗內存的情況,但我的猜測是,您直接訪問伊維爾可以隱式保留週期。試試這個:

-(void)getPhotoSize{ 
    for (PHAsset *asset in _allPhotos) { 
     typeof(self) __weak weakSelf = self; // weak reference to self to avoid retain cycle 
     [[PHImageManager defaultManager] requestImageDataForAsset:asset options:nil resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) { 
      typeof(self) __strong strongSelf = weakSelf; // strong reference to make sure self exists until the block finishes 

      float imageSize = imageData.length; 
      imageSize = imageSize; 
      strongSelf.data.totalPictureSize+=imageSize; 
      strongSelf.currentPhotoAsset=asset; 
     }];   
    } 
} 

我也改變它爲一個規則的循環,以避免嵌套塊。


快速和骯髒的異步版本

-(void)photoSizeWithCompletion:(void (^)(float))completion { 
    NSArray *assets = _allPhotos; 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     float totalSize = 0; 
     for (PHAsset *asset in assets) { 
      [[PHImageManager defaultManager] requestImageDataForAsset:asset options:nil resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) { 
       totalSize += imageData.length; 
      }];   
     }    

     completion(totalSize); 
    }); 
} 

這樣稱呼它:

[someObject photoSizeWithCompletion:^(float totalSize){ 
    // use the totalSize 
}] 

這不支持取消當用戶點擊後退鍵。但我會留下它作爲功課,以查看NSOperationQueue以進行可取消的異步操作。檢查蘋果的文檔operation queues and concurrency

+0

如果我不派遣它阻止我的用戶界面。這就是爲什麼我試圖在後臺線程中運行。 – Shohrab

+0

但是,如果你'dispatch_sync'它仍然會阻塞你的調用者線程。你是否打算使用'dispatch_async'? –

+0

剛剛注意到'data'似乎也是一個ivar,所以使用'strongSelf.data'來訪問它並避免保留週期。 –