sin*_*k12 14 memory objective-c nsoperation nsurlrequest ios
我正在实现一个需要通过HTTP获取大量图像的iOS应用程序.我已经尝试了几种方法但独立完成了我的工作,Instuments显示不断增加的内存分配,并且当我在设备上运行它时,应用程序迟早会崩溃.仪器没有泄漏.
到目前为止,我尝试了以下方法:
Instrumetns中的调用树显示在处理HTTP响应时消耗了内存.在异步NSURLConnection的情况下,这是
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
}
Run Code Online (Sandbox Code Playgroud)
在同步NSURLConnection的情况下,Instruments显示了不断增长的CFData(商店)条目.ASIHTTPRequest的问题似乎与类似代码位置中的异步NSURLConnection相同.[NSData dataWithContentsOfURL:url]方法在exactely该语句中显示了越来越多的总内存分配.
当请求在一个单独的线程中完成时,我正在使用NSAutoReleasePool,我试图用[[NSURLCache sharedURLCache] removeAllCachedResponses]释放内存 - 没有成功.
有什么想法/提示来解决问题吗?谢谢.
编辑: 如果我使用CoreData持久保存图像,则仅显示该行为.这是我作为NSInvocationOperation运行的代码:
-(void) _fetchAndSave:(NSString*) imageId {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *url = [NSString stringWithFormat:@"%@%@", kImageUrl, imageId];
HTTPResponse *response = [SimpleHTTPClient GET:url headerOrNil:nil];
NSData *data = [response payload];
if(data && [data length] > 0) {
UIImage *thumbnailImage = [UIImage imageWithData:data];
NSData *thumbnailData = UIImageJPEGRepresentation([thumbnailImage scaleToSize:CGSizeMake(55, 53)], 0.5); // UIImagePNGRepresentation(thumbnail);
[self performSelectorOnMainThread:@selector(_save:) withObject:[NSArray arrayWithObjects:imageId, data, thumbnailData, nil] waitUntilDone:NO];
}
[pool release];
}
Run Code Online (Sandbox Code Playgroud)
所有与CoreData相关的东西都在Main-Thread中完成,所以不应该有任何CoreData多线程问题.但是,如果我保留图像,仪器会在上述位置显示不断增加的内存分配.
编辑二:
CoreData相关代码:
-(void) _save:(NSArray*)args {
NSString *imageId = [args objectAtIndex:0];
NSData *data = [args objectAtIndex:1];
NSData *thumbnailData = [args objectAtIndex:2];
Image *image = (Image*)[[CoreDataHelper sharedSingleton] createObject:@Image];
image.timestamp = [NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]];
image.data = data;
Thumbnail *thumbnail = (Thumbnail*)[[CoreDataHelper sharedSingleton] createObject:@"Thumbnail"];
thumbnail.data = thumbnailData;
thumbnail.timestamp = image.timestamp;
[[CoreDataHelper sharedSingleton] save];
}
Run Code Online (Sandbox Code Playgroud)
从CoreDataHelper(self.managedObjectContext选择当前线程中可用的NSManagedObjectContext):
-(NSManagedObject *) createObject:(NSString *) entityName {
return [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:self.managedObjectContext];
}
Run Code Online (Sandbox Code Playgroud)
我们遇到了类似的问题.在通过http获取大量图像的同时,内存分配中出现了巨大的增长和锯齿模式.我们会看到系统或多或少地清理,但是很慢,而且不可预测.与此同时,下载量正在流入,堆积在内存上的任何内容上.内存分配将达到200M左右,然后我们就会死亡.
问题是NSURLCache问题.你声明你试过[[NSURLCache sharedURLCache] removeAllCachedResponses].我们也试过了,但后来尝试了一些不同的东西.
我们的下载是在N个图像/电影的组中完成的,其中N通常为50到500.重要的是我们将所有N作为原子操作.
在我们开始使用http下载组之前,我们这样做了:
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:0];
[NSURLCache setSharedURLCache:sharedCache];
Run Code Online (Sandbox Code Playgroud)
然后,我们使用同步调用通过http 获取N中的每个图像.我们在NSOperation中进行此组下载,因此我们不会阻止UI.
NSData *movieReferenceData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
Run Code Online (Sandbox Code Playgroud)
最后,在每个单独的图像下载之后,在我们完成该图像的NSData对象之后,我们调用:
[sharedCache removeAllCachedResponses];
Run Code Online (Sandbox Code Playgroud)
我们的内存分配峰值行为下降到非常舒适的少数几兆字节,并且停止增长.
在这种情况下,您所看到的正是您应该看到的。-[NSMutableData appendData:]增加其内部缓冲区的大小以保存新数据。由于 anNSMutableData始终位于内存中,因此这会导致内存使用量相应增加。你在期待什么?
如果这些图像的最终目标位于磁盘上,请尝试使用NSOutputStream代替NSMutableData. 如果您随后想要显示图像,则可以UIImage在完成后创建指向该文件的指向。
| 归档时间: |
|
| 查看次数: |
5014 次 |
| 最近记录: |