2

我已经搜索过这个问题,但没有得到任何适当的解决方案。在我的应用程序中,我对服务器进行了多次递归异步调用。我正在使用 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 行显示内存泄漏

请参阅显示内存泄漏的仪器屏幕截图

以下是我编写的实际代码:

- (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);
        }
    }];
}

为 self 添加了弱引用,还使用了autorelease 块,但这并没有解决我的问题

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

谢谢!

4

0 回答 0