ios - 计算照片文件夹中的总图像大小
ios - Calculate total image size in photos folder
我正在尝试计算照片文件夹中图像占用的总存储空间。我写的代码如下。我能够成功获取图像,但这段代码有两个问题 -
如果照片有超过 7000 张图片,有时应用会崩溃。从,记录我
理解它的内存问题。
如果我 运行 这段代码多次来回,在 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;
}];
}
}];
});
}
我不明白你是在分派代码而不是 运行ning 它,所以我打算从下面的示例中删除 GCD 部分。您还需要 运行 工具来检查泄漏并找出正在消耗内存的内容,但我的猜测是您通过直接访问 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
以进行可取消的异步操作。查看 Apple 在 operation queues and concurrency.
上的文档
我正在尝试计算照片文件夹中图像占用的总存储空间。我写的代码如下。我能够成功获取图像,但这段代码有两个问题 -
如果照片有超过 7000 张图片,有时应用会崩溃。从,记录我 理解它的内存问题。
如果我 运行 这段代码多次来回,在 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;
}];
}
}];
});
}
我不明白你是在分派代码而不是 运行ning 它,所以我打算从下面的示例中删除 GCD 部分。您还需要 运行 工具来检查泄漏并找出正在消耗内存的内容,但我的猜测是您通过直接访问 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
以进行可取消的异步操作。查看 Apple 在 operation queues and concurrency.