我已经搜索过这个问题,但没有得到任何正确的解决方案。在我的应用程序中,我向服务器提供多个递归异步调用。我正在使用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×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 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 但没有解决我的问题。
在执行递归异步调用时,我可以做些什么来消除内存泄漏或者我做错了什么?
谢谢!