内存泄漏点击屏幕,网络多次,导致真实设备崩溃

时间:2016-11-25 06:58:19

标签: ios memory memory-leaks instruments

当用户测试我的应用时,他随机点击屏幕,就像一只猴子一样,进入我的每个细节view controller,因为每个细节都vcvc来自网络的fetch data。在真实设备中我的应用crash。 我认为此问题是由memory leak引起的,因为这不会出现在simulator中,我会在instrument中测试我的应用,下面是screenshoot

在乐器中:

the instrument

情况:

  1. 我的主屏幕,点击主屏幕上的每个item将显示不同的详细信息vc
  2. my main screen

    1. 详细信息vc,每个详情vc,用户测试fetch data或点击随机:
    2. enter image description here

      1. 内存增长到90.5MB,并且没有降低,如果使用用户的测试方法,如果花费更长的时间,将会超过90.5MB
      2. the memory grow to 90.5MB

        我使用instrument并不是那么好,内存最常用于AFNetworking,我不知道该如何处理。有人可以提供建议吗?非常感谢提前。

        修改

        我将AFHTTPSessionManager设为singleton,但我发现我的网络请求变慢了,这对我有影响吗?

        #import "Mysevers.h"
        #import "AFNetworking.h"
        #import "HUD.h"
        
        
        static AFHTTPSessionManager *requestManager ;
        
        @implementation Mysevers
        
        + (AFHTTPSessionManager *)sharedHTTPSession{
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                requestManager = [AFHTTPSessionManager manager];
                requestManager.requestSerializer.timeoutInterval = 10;
            });
            return requestManager;
        }
        
        
        +(void)AFPOSTWithHud:(BOOL)hud andAddressname:(NSString*)addressName parmas:(NSDictionary*)parmas RequestSuccess:(void(^)(id result))success failBlcok:(void(^)(void))failBlcok
        {
        
            if (hud) {
                //[HUD addHUD];
        
                [SVProgressHUD show];
            }
        
            AFHTTPSessionManager *requestManager = [Mysevers sharedHTTPSession];
        
            NSString *urlStr = [NSString stringWithFormat:@"%@%@",BASE_URL,addressName];
            DLog(@"%@",urlStr);
        
            [requestManager POST:urlStr parameters:parmas progress:^(NSProgress * _Nonnull uploadProgress) {
        
         } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                if (hud) {
                    //[HUD removeHUD];
                    [SVProgressHUD dismiss];
                }
                success(responseObject);
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
                if (error != nil) {
                    DLog(@"error==%@",[error localizedDescription]);
                    if (hud) {
                        //[HUD removeHUD];
                        [SVProgressHUD dismiss];
                    }
                    failBlcok();
                }
        
        
                return ;
            }];
        
        
        }
        
        
        +(void)AFGETWithHud:(BOOL)hud andAddressname:(NSString*)addressName parmas:(NSDictionary*)parmas RequestSuccess:(void(^)(id result))success failBlcok:( void(^)(void))failBlcok
        {    
            if (hud) {
                //[HUD addHUD];
                [SVProgressHUD show];
            }
            AFHTTPSessionManager *requestManager = [Mysevers sharedHTTPSession];
        
            NSString *urlStr = [NSString stringWithFormat:@"%@%@",BASE_URL,addressName];
        
            DLog(@"%@",urlStr);
        
        
            [requestManager GET:urlStr parameters:parmas progress:^(NSProgress * _Nonnull downloadProgress) {
        
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
                if (hud) {
        
                    //[HUD removeHUD];
                    [SVProgressHUD dismiss];
                }
                success(responseObject);
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                DLog(@"error==%@",[error localizedDescription]);
        
                if (hud) {
                    //[HUD removeHUD];
                    [SVProgressHUD dismiss];
                }
                failBlcok();
            }];
        }
        
        
        @end
        

1 个答案:

答案 0 :(得分:0)

如果要实例化大量新的NSURLSession对象(即,如果实例化大量AFHTTPSessionManager个对象,则会发生这种情况),您将看到此行为。

例如,我编写了一个简单的程序,它实例化了50个单独的NSURLSession个对象,为每个对象做了一个简单的数据任务(由#34;指示帖"指定"兴趣",下面,所有都发生在绿色条指示的区域内),然后立即释放它们。

你会看到内存增加了近6mb,但是大约2分钟后(我完全没有干预),它只开始回收那个内存,返回了以前所有内存消耗的一半以上那些会话对象。这是我在发出多个会话对象时看到的可重现模式。

enter image description here

这可以通过调用finishTasksAndInvalidate对象上的NSURLSession来解决,或者更好的方法是确保您的应用程序仅实例化一个会话对象,然后每次都使用相同的会话对象。这些方法中的任何一种都会大大减少应用程序的内存配置文件(重用相同的会话对象只会更有效)。

简而言之,我会确保您的详细视图控制器不会每次都实例化一个新的AFHTTPSessionManager对象。在您的应用中将其实例化一次并重复使用。

话虽如此,我想知道你是否还有一些其他的内存问题,因为我的50 NSURLSession个对象只消耗了6mb的内存,而且听起来你失去了更多。因此,我建议修复上述内容,但如果您仍然看到内存消耗增加(不再需要在泄漏中显示),也许您有一些强大的参考周期等。 Xcode 8"调试内存图"工具(请参阅How to debug memory leaks when Leaks instrument does not show them?)有助于跟踪这些问题。