NSJSONSerialization JSONObjectWithData上的Memoy泄漏

时间:2015-09-30 07:08:18

标签: ios xcode memory-leaks nsjsonserialization mknetworkkit

我已经搜索过这个问题,但没有得到任何正确的解决方案。在我的应用程序中,我向服务器提供多个递归异步调用。我正在使用MKNetworkKit执行网络操作。 我的实现的伪代码:

- updateForms{

     [networkcall completionblock:^(MKNetworkOperation *op){
           dictionaryObject = op.responseJSON
           if(moreForms)
                [self updateForms] // recursive call
           else
                save data in db and proceed further
     }
}

然而,执行上面的代码时,在完成块中的每个调用之后,内存使用量会增加4-10 MB(我想在线字典对象= op.responseJSON)。

使用乐器后,它在MKNetworkKit函数中的NSJSONSerialization JSONObjectWithData行显示内存泄漏

Please refer instruments screenshot showing memory leak

以下是我写的实际代码:

- (void)updateForms:(int)requestCount
{
    /* ====================================
     * update forms from webserver
     * ====================================
     *
     */
    __block int blockRequestCount = requestCount;
    if (UIApplication.sharedApplication.applicationState != UIApplicationStateActive)
    {
        NSLog(@"Background time remaining = %.1f seconds", [UIApplication sharedApplication].backgroundTimeRemaining);
    }
    // get username and password
    NSString *username = [[NSUserDefaults standardUserDefaults] valueForKey:@"username"];
    NSString *userPassword = [[NSUserDefaults standardUserDefaults] valueForKey:@"password"];

    NSString *signature = [NSString stringWithFormat:@"url=%@&action=forms&timestamp=%@", apiBaseURL, [[Utility shareInstance] getCurrentTimeStamp]];

    //signature = [[Utility shareInstance] encodeWithURL:signature];

    NSString *signatures = [[NSString alloc] initWithString:[[Utility shareInstance] hmacSHA256ForKeyAndData:request_PrivateKey withData:signature]];
    NSString *timestamp = [[NSString alloc] initWithString:[[Utility shareInstance] getCurrentTimeStamp]];
    NSMutableDictionary *dic  = [[NSMutableDictionary alloc]init];
    [dic setValue:apiBaseURL forKey:@"url"];
    [dic setValue:timestamp forKey:@"timestamp"];
    [dic setValue:signatures forKey:@"signature"];
    [dic setValue:[NSString stringWithFormat:@"%d",requestCount] forKey:@"request_no"];

    NSString *urlGetForms = [NSString stringWithFormat:@"%@forms", apiBaseURL];

    //[MMProgressHUD setPresentationStyle:MMProgressHUDPresentationStyleFade];
    //[MMProgressHUD showWithTitle:@"iPEGS" status:@"Loading..."];

    if (UIApplication.sharedApplication.applicationState != UIApplicationStateActive)
    {
        NSLog(@"Background time remaining = %.1f seconds", [UIApplication sharedApplication].backgroundTimeRemaining);
    }

    //dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    __weak typeof(self) weakSelf = self;

    //asynchronous code
    [[AppRequest shareInstance] loadRequestWithURL:urlGetForms withLoadingIndicator:NO username:username password:userPassword params:dic success: ^(MKNetworkOperation *op) {

        //dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        typeof(weakSelf) strongSelf = weakSelf;

        if (op != nil){
            if (UIApplication.sharedApplication.applicationState != UIApplicationStateActive){
                NSLog(@"Background time remaining = %.1f seconds", [UIApplication sharedApplication].backgroundTimeRemaining);
            }
            // code modified
            NSMutableDictionary *responseDataTemp;
            @autoreleasepool {
                NSDictionary *dic = op.responseJSON;
                responseDataTemp = [[NSMutableDictionary alloc] initWithDictionary:dic];
            }

            //NSLog(@"responseData:%@\n\n\n",op.responseString);

            [responseDataTemp removeObjectForKey:@"message"];
            [responseData addEntriesFromDictionary:responseDataTemp];

            if ([[responseDataTemp objectForKey:@"form_remaining"] intValue]) {
                [responseData removeObjectForKey:@"form_remaining"];
                NSLog(@"Custom Forms count %lu",(unsigned long)[responseData count]);
                [strongSelf updateForms:++blockRequestCount];
            }else{
                [responseData removeObjectForKey:@"form_remaining"];
                NSLog(@"Custom Forms count %lu",(unsigned long)[responseData count]);

                // Parse response data and save in database
                [strongSelf parseAndSaveData:strongSelf];

                if (strongSelf.backgroundTask != UIBackgroundTaskInvalid){
                    [[UIApplication sharedApplication] endBackgroundTask:strongSelf.backgroundTask];
                    strongSelf.backgroundTask = UIBackgroundTaskInvalid;
                }

                dispatch_async(dispatch_get_main_queue(), ^{

                    //synchronous code
                    [MMProgressHUD dismiss];
                    [responseData removeAllObjects];
                    [customFormIds removeAllObjects];
                    [questionnaireIds removeAllObjects];

                });

                if (UIApplication.sharedApplication.applicationState != UIApplicationStateActive)
                {
                    NSLog(@"Background time remaining = %.1f seconds", [UIApplication sharedApplication].backgroundTimeRemaining);
                }
            }
        }
    } failure: ^(MKNetworkOperation *op, NSError *er) {
        if (er) {

            if (self.backgroundTask != UIBackgroundTaskInvalid){
                [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];
                self.backgroundTask = UIBackgroundTaskInvalid;
            }

            dispatch_async(dispatch_get_main_queue(), ^{

                //synchronous code
                [MMProgressHUD dismiss];
                [responseData removeAllObjects];
                [customFormIds removeAllObjects];
                [questionnaireIds removeAllObjects];
            });


        }
        //NSLog(@"error:%@", er.description);

        if (self.backgroundTask != UIBackgroundTaskInvalid){
            [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];
            self.backgroundTask = UIBackgroundTaskInvalid;
        }

        if (UIApplication.sharedApplication.applicationState != UIApplicationStateActive){
            NSLog(@"Background time remaining = %.1f seconds", [UIApplication sharedApplication].backgroundTimeRemaining);
        }
    }];
}

我添加了自我弱引用并使用 autorelease block 没有解决我的问题

在执行递归异步调用时,我可以做些什么来消除内存泄漏或者我做错了什么?

谢谢!

0 个答案:

没有答案