posts - 186,  comments - 17,  views - 35万
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

最近项目需求,从相册中提取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/9e84fe63d5c0
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    posted on   ZOYOO  阅读(1101)  评论(0编辑  收藏  举报
    编辑推荐:
    · Linux系列:如何用 C#调用 C方法造成内存泄露
    · AI与.NET技术实操系列(二):开始使用ML.NET
    · 记一次.NET内存居高不下排查解决与启示
    · 探究高空视频全景AR技术的实现原理
    · 理解Rust引用及其生命周期标识(上)
    阅读排行:
    · 物流快递公司核心技术能力-地址解析分单基础技术分享
    · .NET 10首个预览版发布:重大改进与新特性概览!
    · 单线程的Redis速度为什么快?
    · 展开说说关于C#中ORM框架的用法!
    · Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
    点击右上角即可分享
    微信分享提示