美文网首页iOS程序员的业余沙龙iOS_RunloopiOS相关
iOS 解决上传100张图片内存奔溃问题

iOS 解决上传100张图片内存奔溃问题

作者: charlotte2018 | 来源:发表于2017-03-11 10:03 被阅读1719次

最近项目需求,从相册中提取100张图片,然后上传到服务器。前提是图片不能压缩。因为要将图片信息采集出来制作出3D模型。所以必须是高清图片。

  • 先看下代码
[NetWorking uploadWithUrl:@"xxx" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        
        for (int i = 0; i<imageArr.count; i++) {
            
                UIImage *image = imageArr[i];
                NSData *data = UIImageJPEGRepresentation(image, 1.0);
                [formData appendPartWithFileData:data name:@"files" fileName:@"xxxx" mimeType:@"image/jpeg"];
            
        }
        
    } withProgress:^(NSProgress *uploadProgress) {
        
    } success:^(id responseObject) {
        
    } failure:^(NSError *error) {
        
   }]

  • 如果imageArr是100或者更大的时候,就会导致奔溃。

  • 模拟器弹出的框子是这样说的。


    3BE4EE0E-5A0F-408E-B3EE-DA9D0BCFDBAE.png
  • 意思就是内存警告直接把app给carsh掉了

屏幕快照 2017-03-11 上午9.52.23.png
  • 我抓拍的瞬间,内存急速暴涨。

原因: 就是因为image,data的局部变量在内存中没有及时释放导致占用内存过大,导致程序被杀死。

解决方法。及时释放局部变量就可以了。在局部变量中间加入自动释放池。


[NetWorking uploadWithUrl:@"xxx" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        
        for (int i = 0; i<imageArr.count; i++) {
            
         @autoreleasepool {
                UIImage *image = imageArr[i];
                NSData *data = UIImageJPEGRepresentation(image, 1.0);
                [formData appendPartWithFileData:data name:@"files" fileName:@"xxxx" mimeType:@"image/jpeg"];

         }
            
        }
        
    } withProgress:^(NSProgress *uploadProgress) {
        
    } success:^(id responseObject) {
        
    } failure:^(NSError *error) {
        
   }]

自动释放池概述

自动释放池被置于一个堆栈中,虽然它们通常被称为被“嵌套”的。当您创建一个新的自动释放池时,它被添加到堆栈的顶部。当自动释放池被回收时,它们从堆栈中被删除。当一个对象收到送autorelease消息时,它被添加到当前线程的目前处于栈顶的自动释放池中。你不能向自动释放池发送autorelease或retain消息。Application Kit会在一个事件周期(或事件循环迭代)的开端—比如鼠标按下事件—自动创建一个自动释放池,并且在事件周期的结尾释放它,因此您的代码通常不必关心。 有三种情况您应该使用您自己的自动释放池:

如果您正在编写一个不是基于Application Kit的程序,比如命令行工具,则没有对自动释放池的内置支持;您必须自己创建它们。

如果您生成了一个从属线程,则一旦该线程开始执行,您必须立即创建您自己的自动释放池;否则,您将会泄漏对象。

如果您编写了一个循环,其中创建了许多临时对象,您可以在循环内部创建一个自动释放池,以便在下次迭代之前销毁这些
对象。这可以帮助减少应用程序的最大内存占用量。

队列上传看我这篇文章

http://www.jianshu.com/p/5162df747879

相关文章

网友评论

  • Star啓航:我也遇到了这种问题,上传图片功能一次性上传6张,在iphone6上时,第一次上传6张图片就会闪退,加了autoreleasepool之后,第一次上传就不会闪退了,但是紧接着第二次上传还是会导致闪退。我看了下内存,其实跟第一次相比并没有增加多少,为什么还是会出现闪退的问题呢?求大佬指教一下
  • 小石头JS:用到了,感谢分享~
  • 是你丶:很奇怪的问题,我现在做了一个单独的app,使用上传图片功能,也不多 最多一次6张,进行了压缩。然后将此app当做一个模块集成到另一个app中,同样的代码,上传1张可以,多张就会卡死,也不崩溃,过一会提示连接超时,但其实根本没有走请求。模拟器没问题,iPhone7以下的真机会出现这种问题,也加了自动释放池,求解呀。

本文标题:iOS 解决上传100张图片内存奔溃问题

本文链接:https://www.haomeiwen.com/subject/msragttx.html