iOS下载和解析大型JSON响应会导致CFData(存储)泄漏 [英] iOS Download & Parsing Large JSON responses is causing CFData (store) leaks
问题描述
用户第一次打开我的应用程序时,我需要下载大量数据.我从服务器以JSON形式获取所有这些数据.根据用户的不同,这些JSON文件的大小可以在10kb-30mb之间,并且有十多种.
The first time a user opens my app I need to download lots of data. I get all of this data from the server in JSON form. Depending on the user, these JSON files can be anywhere from 10kb - 30mb each, and there are 10+ of them.
当JSON的记录不超过500条时,我这样做没有问题,但是就像我说的那样,其中一些记录有10,000+条记录,最大可以达到30mb.
I have no problems doing this when the JSONs have no more than 500 or so records, but like I said some have 10,000+ records and can be up to 30mb in size.
下载较大的JSON时,我的应用程序会分配大量内存,直到最终收到内存警告并且应用程序崩溃为止.
When downloading the larger JSONs, my app allocs a ton of memory, until I eventually get memory warnings and the app blows up.
似乎CFData必须是我在didReceiveData中构建的NSMutableData.当我下载一个JSON时,CFData(存储)会上升-当我开始解析时,它会停止上升.
在继续下载& ;;之前,我该如何清除这些数据?解析下一个JSON?
How can I clear out that data before moving on to download & parse the next JSON?
如下所示,内存中有200mb的CFData(存储):
As you can see below, there is 200mb of CFData (store) sitting around in memory:
-
深入研究CFData并不能帮助我很多:
Digging into the CFData doesn't reveal much to help me:
这是我在其中创建用于获取这些各种JSON的操作的代码-
Here is the code where I create operations to get these various JSONs--
- (void)checkForUpdates
{
if(!_globals)
_globals = [MySingleton sharedInstance];
MyAFHTTPClient* client = [MyAFHTTPClient sharedClient];
NSString* path = [NSString stringWithFormat:@"cache?deviceUID=%@&token=%@",[_globals getMacAddress], [_globals getToken]];
NSURLRequest* request = [client requestWithMethod:@"GET" path:path parameters:nil];
_currentEnvironment = [_globals getActiveEnvironment];
if(!_currentEnvironment.didDownloadDataValue)
[self setupAndShowHUDinView:self.view withText:@"Checking for updates..."];
AFJSONRequestOperation* operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
for(NSString *str in [JSON valueForKey:@"Views"])
{
//for each table i need to update, create a request to
NSString* path = [NSString stringWithFormat:@"cache/%@/?deviceUID=%@&token=%@", str, @"00000-00000-0000-00001", [_globals getToken]];
NSURLRequest* request = [client requestWithMethod:@"GET" path:path parameters:nil];
AFJSONRequestOperation* operation2 = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON)
{
// even if this is comment this out and I do nothing but download, app crashes
//[self updateTable:str withJSON:JSON];
} failure:nil];
[operation2 setSuccessCallbackQueue:backgroundQueue];
[client.operationQueue addOperation:operation2];
numRequests++;
}
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
}];
[operation start];
}
CFData是我在内存中的JSON响应吗?我试图清除我的NSURLCache时没有运气-
Is that CFData my JSONs responses that are in memory? I have attempted to clear my NSURLCache with no luck--
我也对JSON流进行了一些研究..这对减少内存中的对象数量有帮助吗?
I have also looked a little into JSON streaming.. would that help me at all to reduce the amount of objects in memory?
除了我能想到的唯一其他选择,是实现某种分页..但我需要我的用户拥有所有数据
Besides that the only other option I can think of is implementing some sort of paging..but I need my users to have all of the data
任何帮助/建议都将不胜感激!谢谢!
Any help/suggestions is greatly appreciated! Thanks!
-
编辑
好吧,我决定使用剥离AFNetworking并尝试使用本机功能.通过这样做,我仍然可以获得相同的CFData版本.我正在使用此NSOperation子类并且我现在正在创建/添加我的操作,如下所示:
Ok I decided to use strip out AFNetworking and try to use native functions. In doing this I still get the same build of of CFData. I am using this subclass of NSOperation and I am creating/ adding my operations as follows now:
NSOperationQueue *operationQueue;
operationQueue = [[NSOperationQueue alloc]init];
[operationQueue setMaxConcurrentOperationCount:1];
for(NSString *str in [views valueForKey:@"Views"])
{
NSString* path = [NSString stringWithFormat:@"%@cache/%@/?deviceUID=%@&token=%@", _globals.baseURL, str, @"00000-00000-0000-00001", [_globals getToken]];
LibSyncOperation *libSyncOperation = [[LibSyncOperation alloc] initWithURL:path];
[operationQueue addOperation:libSyncOperation];
}
推荐答案
我使用具有大量数据的本机JSON转换功能,而没有内存问题.
I use the native JSON conversion functions with massive amounts of data with no memory problems.
我只是使用标准的NSURLConnection
下载NSData
,然后执行以下操作...
I just use a standard NSURLConnection
to download the NSData
then do the following...
NSData *data = [NSURLConnection sendSynchronous...
// use NSDictionary or NSArray here
NSArray *array = [NSJSONSerialization JSONObjectWithData:data ...
Now deal with the objects.
没有泄漏,因为它是本机函数.比第三方框架快很多.
No leaks as it's a native function. A lot quicker than third parts frameworks.
这篇关于iOS下载和解析大型JSON响应会导致CFData(存储)泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!