iOS两个内存问题(UIImagePickerController和UINavigationController的内存释放)

一、UIImagePickerController


日常开发中,UIImagePickerController是经常使用的类,可以方便的调用相册和系统照相机,但是因为图片过大会导致内存暴涨,如果调用次数过多甚至内存泄漏导致应用内存警告或崩溃。下面便探讨一下对策。

下面这种方法,image是一直在内存中不被释放,即使viewController-dealloc之后,也没有释放。

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
    imageView.image = image;
    [picker dismissViewControllerAnimated:YES completion:NULL];
}

程序正常使用内存情况:

iOS两个内存问题(UIImagePickerController和UINavigationController的内存释放)_第1张图片
正常内存.png

从相册选取两张图的内存情况:

iOS两个内存问题(UIImagePickerController和UINavigationController的内存释放)_第2张图片
调用后内存.png

原以为是哪里写错了,下了苹果的演示代码也会有这种情况,这是苹果源码里的警告

/* Start the timer to take a photo every 1.5 seconds.
CAUTION: for the purpose of this sample, we will continue to take pictures indefinitely.
Be aware we will run out of memory quickly. You must decide the proper threshold number of photos allowed to take from the camera.
One solution to avoid memory constraints is to save each taken photo to disk rather than keeping all of them in memory.
In low memory situations sometimes our "didReceiveMemoryWarning" method will be called in which case we can recover some memory and keep the app running.
*/

自己解决吧(Google)

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    UIImage *image = [self processImage:[info objectForKey:UIImagePickerControllerOriginalImage]];
   imageView.image = image;
    [picker dismissViewControllerAnimated:YES completion:NULL];
}
//如果要上传到服务器,最好在压缩一下UIImageJPEGRepresentation(image, 0-1)
- (UIImage *)processImage:(UIImage *)image {
    CGFloat hFactor = image.size.width / RQGScreenWidth;
    CGFloat wFactor = image.size.height / RQGScreenHeight;
    CGFloat factor = fmaxf(hFactor, wFactor);
    CGFloat newW = image.size.width / factor;
    CGFloat newH = image.size.height / factor;
    CGSize newSize = CGSizeMake(newW, newH);
    UIGraphicsBeginImageContext(newSize);
    [image drawInRect:CGRectMake(0, 0, newW, newH)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

这种方法内存情况:

iOS两个内存问题(UIImagePickerController和UINavigationController的内存释放)_第3张图片
改善后内存.png

选很多张图片内存都不会暴涨
虽还是不完美,但很有用。


二、UINavigationController

说一下碰到的UINavigationController 中,pop后的controller不走dealloc方法的原因


1、有强引用(比如viewController是的一个未释放的viewController的属性)
2、定时器没有invalidate
3、网络请求没结束(包括AFN,ASI,SDWebImage)

你可能感兴趣的:(iOS两个内存问题(UIImagePickerController和UINavigationController的内存释放))