一、UIImagePickerController
日常開(kāi)發(fā)中锅纺,UIImagePickerController是經(jīng)常使用的類祝拯,可以方便的調(diào)用相冊(cè)和系統(tǒng)照相機(jī),但是因?yàn)閳D片過(guò)大會(huì)導(dǎo)致內(nèi)存暴漲,如果調(diào)用次數(shù)過(guò)多甚至內(nèi)存泄漏導(dǎo)致應(yīng)用內(nèi)存警告或崩潰。下面便探討一下對(duì)策。
下面這種方法漾抬,image是一直在內(nèi)存中不被釋放,即使viewController-dealloc之后陶耍,也沒(méi)有釋放奋蔚。
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
imageView.image = image;
[picker dismissViewControllerAnimated:YES completion:NULL];
}
程序正常使用內(nèi)存情況:
正常內(nèi)存.png
從相冊(cè)選取兩張圖的內(nèi)存情況:
調(diào)用后內(nèi)存.png
原以為是哪里寫錯(cuò)了,下了蘋果的演示代碼也會(huì)有這種情況烈钞,這是蘋果源碼里的警告
/* 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<NSString *,id> *)info {
UIImage *image = [self processImage:[info objectForKey:UIImagePickerControllerOriginalImage]];
imageView.image = image;
[picker dismissViewControllerAnimated:YES completion:NULL];
}
//如果要上傳到服務(wù)器泊碑,最好在壓縮一下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;
}
這種方法內(nèi)存情況:
改善后內(nèi)存.png
選很多張圖片內(nèi)存都不會(huì)暴漲
雖還是不完美,但很有用毯欣。
二馒过、UINavigationController
說(shuō)一下碰到的UINavigationController 中,pop后的controller不走dealloc方法的原因
1酗钞、有強(qiáng)引用(比如viewController是的一個(gè)未釋放的viewController的屬性)
2腹忽、定時(shí)器沒(méi)有invalidate
3来累、網(wǎng)絡(luò)請(qǐng)求沒(méi)結(jié)束(包括AFN,ASI窘奏,SDWebImage)