IApp正在泄露记忆

时间:2015-03-20 07:03:42

标签: objective-c memory-leaks afnetworking-2

我通过仪器运行我的应用程序,看看是否有任何内存泄漏。我注意到有两个漏洞出现了。一次泄漏只发生在启动时,这是:

第4行是代码中令人讨厌的代码:

    static id (*_old_UIStoryboard_instantiateViewControllerWithIdentifier_)(UIStoryboard *self, SEL _cmd, NSString *identifier);
static id _UIStoryboard_instantiateViewControllerWithIdentifier_(UIStoryboard *self, SEL _cmd, NSString *identifier)
{
    id ret = _old_UIStoryboard_instantiateViewControllerWithIdentifier_(self, _cmd, identifier);

    if ([[self delegate] respondsToSelector:@selector(storyboard:didInstantiateViewController:withIdentifier:)])
        [[self delegate] storyboard:self didInstantiateViewController:ret withIdentifier:identifier];

    return ret;
}

我遇到的最大漏洞实际上是AFNetworking代码。我不确定我所做的事情是否会导致它。在类文件中:AFURLSessionManager.m

- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration {
    self = [super init];
    if (!self) {
        return nil;
    }

    if (!configuration) {
        configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    }

    self.sessionConfiguration = configuration;

    self.operationQueue = [[NSOperationQueue alloc] init];
    self.operationQueue.maxConcurrentOperationCount = 1;

    self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];

    self.responseSerializer = [AFJSONResponseSerializer serializer];

    self.securityPolicy = [AFSecurityPolicy defaultPolicy];

    self.reachabilityManager = [AFNetworkReachabilityManager sharedManager];

    self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init];

    self.lock = [[NSLock alloc] init];
    self.lock.name = AFURLSessionManagerLockName;

    [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
        for (NSURLSessionDataTask *task in dataTasks) {
            [self addDelegateForDataTask:task completionHandler:nil];
        }

        for (NSURLSessionUploadTask *uploadTask in uploadTasks) {
            [self addDelegateForUploadTask:uploadTask progress:nil completionHandler:nil];
        }

        for (NSURLSessionDownloadTask *downloadTask in downloadTasks) {
            [self addDelegateForDownloadTask:downloadTask progress:nil destination:nil completionHandler:nil];
        }
    }];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidResume:) name:AFNSURLSessionTaskDidResumeNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidSuspend:) name:AFNSURLSessionTaskDidSuspendNotification object:nil];

    return self;
}

上述方法中的这些行显示为泄漏内存 - 每次调用此方法时:

  if (!configuration) {
    configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
}

 self.operationQueue = [[NSOperationQueue alloc] init];

更糟糕的是泄漏次数最多:

 self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];

而且:

self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init];

然后是最后一个:

 self.securityPolicy = [AFSecurityPolicy defaultPolicy];

我该如何解决这些泄漏?另外,我想知道他们为什么泄漏记忆而不仅仅是解决方案,想了解更多关于这些案例的信息。

1 个答案:

答案 0 :(得分:0)

尝试在块中使用weak_self,而不是self,例如:

__weak ClassName *weak_self = self;
    [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
        for (NSURLSessionDataTask *task in dataTasks) {
            [weak_self addDelegateForDataTask:task completionHandler:nil];
        }

        for (NSURLSessionUploadTask *uploadTask in uploadTasks) {
            [weak_self addDelegateForUploadTask:uploadTask progress:nil completionHandler:nil];
        }

        for (NSURLSessionDownloadTask *downloadTask in downloadTasks) {
            [weak_self addDelegateForDownloadTask:downloadTask progress:nil destination:nil completionHandler:nil];
        }
    }];