AFNetworking CFData 泄漏?
Posted
技术标签:
【中文标题】AFNetworking CFData 泄漏?【英文标题】:AFNetworking CFData Leak? 【发布时间】:2013-06-03 16:21:00 【问题描述】:我在使用 AFNetworking 时遇到问题。 我正在使用以下方式通过 GET 从我的服务器请求大量 JSON 数据:
[[SessionResponseClient sharedClient] getPath:kURIRateList parameters:@... success:^(AFHTTPRequestOperation *operation, id JSON)
[_delegate receivedRateResponse:JSON];
failure:^(AFHTTPRequestOperation *operation, NSError *error)
[_delegate receivedRateResponse:nil];
];
当这被调用大约 10-20 次时,CFData 似乎占用了我应用程序的大部分已用内存。
内存使用
当我调查 CFData 和 CFData(存储)时,我得到以下信息:
CFData(存储)
CFData
旁注:我的应用正在使用 ARC,其他一切似乎都运行良好。
我现在的问题是,因为我在 AFNetworking 的 GitHub 页面上没有看到任何悬而未决的问题,并且在互联网上几乎没有其他投诉,我到底做错了什么?还有其他人吗?面对这个问题还是只有我一个?能否请您发布您的代码,因为我认为我的代码看起来没有错误...
更新 1
接口代码:
@protocol RateRequestsDelegate;
@interface RateRequests : NSObject
id<RateRequestsDelegate> _delegate;
@property (nonatomic, strong) id<RateRequestsDelegate> delegate;
- (void)fetchRateList;
@end
@protocol RateRequestsDelegate <NSObject>
- (void)receivedRateResponse:(NSDictionary *)response;
@end
SessionResponseClient 只是一个扩展的 AFHtttpClient 实例,正如所有 AFNetworking 示例所展示的,请参阅:Interact with an API
receiverRateResponse 的代码:
- (void)receivedRateResponse:(NSDictionary *)json
if (!json)
return;
self.moviesToInsert = [NSMutableArray arrayWithArray:[json objectForKey:@"rated"]];
[self.tableView reloadData];
更新 2
我现在将回调更改为基于块的函数,而不是使用委托,它有所改进,但几乎没有提及,也可能是由其他东西的副作用引起的。你们如何实现这一点?尝试获取数据,将其显示在表格或滚动视图中,然后从服务器中多次提取这些数据并刷新视图
非常感谢!保罗
【问题讨论】:
向我们展示 [_delegate receivedRateResponse:JSON];请 这是在设备上还是模拟器上? 和SessionResponseClient的接口 在设备上 - iPad 第 1 代,ios 5.1.1。添加了请求的代码... 您是否在启用 Zombies 的情况下运行?我已经看到这会导致大型 JSON blob 出现问题。 【参考方案1】:谢谢老兄-我遇到了完全相同的问题-您的解决方案有效。
但是,我想我会在您的解决方案中评论说,一旦您收到内存警告,您实际上就是在关闭 NSURLCache。我不确定 AFNetworking 究竟是如何使用 NSURLCache 的,但我假设如果您将其关闭(即通过将其容量设置为 0),它们的实现将不会有效地工作。在您的第一次内存警告之后,这可能会减慢请求速度。作为一种极端情况,您甚至可能会在使用应用几天后遇到意外行为,因为它可能要到第一次内存警告才会出现。
我建议实现一些东西来删除缓存的响应,但保持缓存处于活动状态:
-(void)didReceiveMemoryWarning
[[NSURLCache sharedURLCache] removeAllCachedResponses];
唯一的问题是 AFNetworking 可能需要再次建立其缓存,但我假设这不会对框架产生太大影响。
最后,以防万一它对您或任何人有用 - 为了将您自己的方法注册到内存警告通知中,您可以这样做:
[[NSNotificationCenter defaultCenter] addObserver:self (or pointer to your singleton)
selector:@selector(myMethod)
name:UIApplicationDidReceiveMemoryWarningNotification
object:nil];
希望对你有帮助!
【讨论】:
【参考方案2】:好的,解决方案是CFData (store)
似乎负责在使用NSURLConnection
时将url缓存保存在内存中。
所以我所要做的就是打电话......
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
...清除缓存,一旦我收到内存警告...
或者您可以随时调用它(虽然没有时间分析该功能)...
希望这对遇到类似问题的人有所帮助。
【讨论】:
这将在第一次禁用所有 NSURLCaching,并且对以后的调用没有影响,除了浪费更多内存(除非您稍后在其他地方创建不同的 NSURLCache。)[[NSURLCache sharedURLCache] removeAllCachedResponses];
会更多建议。【参考方案3】:
也许你可以试试@autoreleasepool。 例如:
@autoreleasepool
// your codes below
[[SessionResponseClient sharedClient] getPath:kURIRateList parameters:@... success:^(AFHTTPRequestOperation *operation, id JSON)
[_delegate receivedRateResponse:JSON];
failure:^(AFHTTPRequestOperation *operation, NSError *error)
[_delegate receivedRateResponse:nil];
];
// your codes above
【讨论】:
以上是关于AFNetworking CFData 泄漏?的主要内容,如果未能解决你的问题,请参考以下文章