ios - Memoy leak on NSJSONSerialization JSONObjectWithData -
i have searched problem didn't proper solution. in application giving multiple recursive asynchronous calls server. using mknetworkkit performing network operation. pseudocode of implementation:
- updateforms{ [networkcall completionblock:^(mknetworkoperation *op){ dictionaryobject = op.responsejson if(moreforms) [self updateforms] // recursive call else save data in db , proceed further } }
however while executing above code memory usage getting increased 4 - 10 mbs after each call in completion block(i think on line dictionaryobject = op.responsejson).
after using instruments, showing memory leak @ line nsjsonserialization jsonobjectwithdata in mknetworkkit function:
following actual code have written:
- (void)updateforms:(int)requestcount { /* ==================================== * update forms webserver * ==================================== * */ __block int blockrequestcount = requestcount; if (uiapplication.sharedapplication.applicationstate != uiapplicationstateactive) { nslog(@"background time remaining = %.1f seconds", [uiapplication sharedapplication].backgroundtimeremaining); } // username , password nsstring *username = [[nsuserdefaults standarduserdefaults] valueforkey:@"username"]; nsstring *userpassword = [[nsuserdefaults standarduserdefaults] valueforkey:@"password"]; nsstring *signature = [nsstring stringwithformat:@"url=%@&action=forms×tamp=%@", 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 , 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); } }]; }
i have added weak reference self , using autorelease block not solving issue.
what can remove memory leak or doing wrong while doing recursive asynchronous calls?
thanks!
Comments
Post a Comment