PhotoKit那些坑

1.首先说第一个坑
我们项目是一个老的项目图片选择,浏览都是用的ALAssetsLibrary这个框架,但是自从iOS8之后就废弃了,以至于引来了现在的问题,突然有一天公司一个老总问我,在他手机里面选择照片的时候,打开相册只显示几张照片,当时我一脸懵逼,我他么的怎么知道这是砸回事,手机有毛病吧可能,于是开始查资料,后来没解决,再突然有一天公司又来了一个测试人员,她的手机也是相册只显示几张图片,我开始重视这个问题了,于是开始认真查资料,同时此bug被列为一级bug,不得不解决.
查了半天终于有点眉目,原来ALAssetsLibrary这个框架是不能获取iCloud里面的图片,而PhotoKit这个框架可以,就两行代码PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.networkAccessAllowed = YES;就是这个YES 允许了下载ICloud上面的图片.
2.第二个坑:先看一段代码如下

for(PHAsset *asset in self.assets) {
    // This autorelease pool seems good (a1)
    @autoreleasepool {
        NSLog(@"started requesting image %i", i);
        [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFit options:[self imageRequestOptions] resultHandler:^(UIImage *image, NSDictionary *info) {
            dispatch_async(dispatch_get_main_queue(), ^{
                //you can add autorelease pool here as well (a2)
                @autoreleasepool {
                    assetCount++;
                    NSError *error = [info objectForKey:PHImageErrorKey];
                    if (error) NSLog(@"Image request error: %@",error);
                    else {
                        NSString *imagePath = [appDelegate.docsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%i.png",i]];
                        NSData *imageData = UIImagePNGRepresentation(image);
                        if(imageData) {
                            [imageData writeToFile:imagePath atomically:YES];
                            [self.imagesArray addObject:imagePath];
                        }
                        else {
                            NSLog(@"Couldn't write image data to file.");
                        }
                        [self checkAddComplete];
                        NSLog(@"finished requesting image %i", i);
                    }
                } //a2 ends here
            });
        }];
        i++;
    } // a1 ends here
}

这段代码是我在stackoverflow上看到的,此代码的功能是遍历相册里面所有的图片,然后遍历出UIImage对象(我遇到的问题是遍历的过程中假如一下子遍历上百张图片内存会暴涨,达到了1.1G,然后崩溃)与我写的代码一对比就是比我多写了一个自动释放池,我照他的代码多加一个autoreleasepool问题依旧没解决,继续查资料,看API,我发现了一个与requestImageForAsset方法很像的方法:requestImageDataForAsset,两者差别就是UIImage和NSData,这个api是快下班的时候看到的当时感觉没用,就没去尝试,第二天查资料有人说跟它可能有关系,原因是直接遍历出UIImage对象的时候会造成图片渲染,而requestImageDataForAsset这个方法不会,于是尝试一番,结果让我喜出望外,一下子选择100张图片上传,内存最多不超过200,我感觉还可以,于是就先这样吧,问题解决了.

3.第三个问题PHImageManagerMaximumSize 这个api的意思就是遍历图片时获取原图尺寸,如果你要是想九宫格那个显示的,最好把它改为CGSize(100,100),自己定一个尺寸,内存也不会飙升了
问题总结:利用好自动释放池autoreleasepool,做到内存及时释放,查找造成内存暴涨的代码,分段注释查找,很容易找到,还有遇到感觉可以解决问题的api,一定要多try几次,实践出真知!

下面附上正确的代码:

-(void)reloadImageData
{

    MJWeakSelf;//此宏是MJ刷新自带的一个快速定义一个WeakSelf
    for(int i=0;i<_assetArray.count;i++){
        NSDictionary *dic = [_dataList objectAtIndex:i];
        NSString *imgUrl = [dic objectForKey:@"imgUrl"];
        @autoreleasepool {
            PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
            options.synchronous = YES;
            PHFetchResult *phFetchResult = [PHAsset  fetchAssetsWithLocalIdentifiers:@[imgUrl]  options: nil ];
            [phFetchResult   enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx,BOOL *_Nonnull stop) {
                NSLog(@"obj======%@",obj);
                PHAsset * asset = obj;
                @autoreleasepool {
                    [[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info)
                     {
                     dispatch_async(dispatch_get_main_queue(), ^{
                         @autoreleasepool {
                             UIImage *image = [UIImage imageWithData:imageData];;
                             [weakSelf.dataList addObject:image];
                         }
                     });
                     }];
                }
            }];
        }
}

<PHFetchResult *phFetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[imgUrl] options: nil ];讲一下这行代码,这段代码的意思是通过图片的一个图片的LocalIdentifier(唯一标识符来)查找相册里面的图片,当时想用PHAsset另外一个方法:fetchAssetsWithALAssetURLs通过URL来找本地的图片,但是怕他有时候找不到URL,不靠谱于是就用了fetchAssetsWithLocalIdentifiers它.
有什么讲解不对的地方欢迎指正,一起进步,谢谢

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342