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

时间:2016-08-16 20:27:49

标签: ios objective-c storage objective-c-blocks

我正在尝试按照照片文件夹中的图像计算总存储量。我编写如下代码。我能够成功获取图像,但这段代码有两个问题 -

  1. 如果照片有超过7000张图片,有时应用会崩溃。从,记录我 了解它的内存问题。

  2. 如果我经常来回运行此代码,6-7次后应用程序崩溃。

  3. 任何想法都会非常有用。我需要单独计算视频和歌曲的存储空间

    -(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;
                    }];
                }
            }];
        });
    }
    

1 个答案:

答案 0 :(得分:0)

我不明白你是在派遣代码而不仅仅是运行它,所以我要从下面的示例中删除GCD部分。您还需要运行Instruments来检查泄漏并找出消耗内存的内容,但我的猜测是您通过直接访问ivar来隐式保留周期。试试这个:

-(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;
        }];        
    }
}

我还将其更改为常规for循环以避免嵌套块。

快速和脏的异步版

-(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的Apple文档。