【发布时间】:2013-11-30 10:25:42
【问题描述】:
下面是带有代码的方法,其中我使用手动内存管理出现内存泄漏。内存泄漏是通过使用 Xcode 工具检测到的,并且特别指向我正在使用 NSJSONSerialization 的行。我正在运行目标应用程序(在装有 iOS 6.1 的设备上)。
我第一次点击刷新按钮时没有泄漏。任何后续点击都会产生泄漏(如果我继续点击按钮,则会产生更多泄漏)。下面是代码 - 这是使用 JSON Web 服务的基本内容(Web 服务链接是伪造的,但我使用的真实链接有效)。您会注意到我正在使用 Grand Central Dispatch,这样我就可以更新 UI 而无需等待 JSON 的解析完成。
仪器检测到的线被星号包围。我想为可能对这里发生的事情有所了解的任何人提供帮助。完整的堆栈跟踪(如下 cmets 中提到的,我将放在这里:)
+(NSJSONSerialization JSONObjectWithData:option:error:] -> -[_NSJSONReader parseData:options:] -> -[_NSJSONReader parseUTF8JSONData:skipBytes:options]->newJSONValue->newJSONString->[NSPlaceholderString initWithBytes:length:encoding:]
-(void)parseDictionary:(NSDictionary *)dictonary{
self.transactions = [dictonary objectForKey:@"transactions"];
if(!self.transactions){
NSLog(@"Expected 'transactions' array");
return;
}
for (int arrayIndex = 0; arrayIndex < [self.transactions count]; arrayIndex++) {
TransactionResult *result = [[[TransactionResult alloc] init] autorelease];
result.transactionID = [[self.transactions objectAtIndex:arrayIndex] objectForKey:@"ID"];
result.transactionDescription = [[self.transactions objectAtIndex:arrayIndex] objectForKey:@"description"];
result.transactionPrice = [[self.transactions objectAtIndex:arrayIndex] objectForKey:@"price"];
self.totalPrice += [result.transactionPrice doubleValue];
NSLog(@"total price: %f", self.totalPrice);
[self.transactionResults addObject:result];
result = nil;
}
}
- (IBAction)refreshButtonPressed:(UIBarButtonItem *)sender {
__block id resultObject;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
NSURL *url = [NSURL URLWithString:@"http://mywebservice.php"];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error;
***resultObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];***
if(!error){
if([resultObject isKindOfClass:[NSDictionary class]]){
NSDictionary *dictonary = resultObject;
[self parseDictionary:dictonary];
NSLog(@"Done parsing!");
dispatch_async(dispatch_get_main_queue(), ^{
self.isLoading = NO;
[self.transactionsTableView reloadData];
});
}
else{
NSLog(@"JSON Error: Expected Dictionary");
resultObject = nil;
return;
}
}
else{
NSLog(@"JSON Error: %@", [error localizedDescription]);
dispatch_async(dispatch_get_main_queue(), ^{
resultObject = nil;
[self.transactionsTableView reloadData];
[self showError];
});
return;
}
});
}
【问题讨论】:
-
我的第一个问题始终是您是否有不能切换到 ARC 的原因。
-
因为不幸的是我必须支持 iOS 4.3。
-
在这种情况下,好消息... iOS 4.3 支持 ARCLite。 ARCLite 是没有归零弱引用的 ARC。见Objective-C Feature Availability Index。
-
那很好 - 感谢您的链接。但是,我想找出手头的问题,而不是想办法解决它。
-
好吧,努力吧... :-)
parseDictionary是什么样的?另外,我认为您不需要在第一个else分支中的resultObject上调用release,因为它应该是自动释放的。是否有任何else分支被执行?
标签: ios memory-management memory-leaks nsjsonserialization xcode-instruments