3

我在使用 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 存储内存

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 示例所展示的,请参阅:与 API 交互

receivedRateResponse 的代码:

- (void)receivedRateResponse:(NSDictionary *)json {
  if (!json)    {
    return;
  }

  self.moviesToInsert = [NSMutableArray arrayWithArray:[json objectForKey:@"rated"]];

  [self.tableView reloadData];
}

更新 2

我现在将回调更改为基于块的函数而不是使用委托,并且它有所改进,但几乎没有提及,也可能是由其他东西的副作用引起的。你们如何实现这一点?尝试获取数据,将其显示在表格或滚动视图中,然后从服务器中多次提取这些数据并刷新视图

非常感谢!保罗

4

3 回答 3

2

谢谢老兄-我遇到了完全相同的问题-您的解决方案有效。

但是,我想我会评论说,在您的解决方案中,一旦收到内存警告,您实际上就是在关闭 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];

我希望这会有所帮助!

于 2013-06-19T17:01:45.027 回答
1

好的,解决方案CFData (store)似乎负责在使用NSURLConnection's.

所以我所要做的就是打电话...

NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];

...清除缓存,一旦我收到内存警告...

或者您可以随时调用它(虽然没有时间分析该功能)...

希望这可以帮助遇到类似问题的人。

于 2013-06-04T14:00:33.687 回答
0

也许你可以试试@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

}
于 2015-06-16T01:45:50.900 回答