ios - 计算照片文件夹中的总图像大小

问题描述:

我想通过照片文件夹中的图像计算总存储量。我写了如下代码。我能够成功抓取的图像,但这段代码有两个问题 -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

存储我不明白你在调度的代码,而不是仅仅运行它,所以我要删除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'来访问它并避免保留周期。 –