我正在开发一个 iOS 应用程序,它向我的串行队列分派了相当多的任务。任务是从我的网络服务器下载图像,将其保存到磁盘,然后显示在UIImageView
. 但是,[NSURLConnection sendAsynchrousRequest]
在 iOS 杀死我的进程之前,它将继续消耗越来越多的内存。
下载器方法如下所示:
// dispatch_queue_t is created once by: m_pRequestQueue = dispatch_queue_create( "mynamespace.app", DISPATCH_QUEUE_SERIAL);
- (void) downloadImageInBackgroundWithURL:(NSString*) szUrl {
__block typeof(self) bSelf = self;
__block typeof(m_pUrlRequestQueue) bpUrlRequestQueue = m_pRequestQueue;
dispatch_async( m_pRequestQueue, ^{
NSAutoreleasePool *pAutoreleasePool = [[NSAutoreleasePool alloc] init];
NSURLRequest *pRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:szUrl]
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:URL_REQUEST_TIMEOUT];
[NSURLConnection sendAsynchronousRequest:pRequest queue:bpUrlRequestQueue completionHandler:^(NSURLResponse *pResponse, NSData *pData, NSError *pError) {
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
if ( pError != nil ) {
} else {
// convert image to png format
UIImage *pImg = [UIImage imageWithData:pData];
NSData *pDataPng = UIImagePNGRepresentation(pImg);
bool bSaved = [[NSFileManager defaultManager] createFileAtPath:szCacheFile contents:pDataPng attributes:nil];
}
__block typeof(pDataPng) bpDataPng = pDataPng;
__block typeof(pError) bpError = pError;
dispatch_sync( dispatch_get_main_queue(), ^ {
NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
UIImage *pImage = [[UIImage alloc] initWithData:bpDataPng];
// display the image
[pImage release];
// NSLog( @"image retain count: %d", [pImage retainCount] ); // 0, bad access
[autoreleasepool drain];
});
}
[pPool drain];
}]; // end sendAsynchronousRequest
[pAutoreleasePool drain];
}); // end dispatch_async
} // end downloadImageInBackgroundWithURL
我很确定它是内部[NSURLConnection sendAsynchronousRequest]
的东西,因为分析器显示该函数是占用所有内存的函数......
但是,我也不太确定 dispatch_*** 和阻塞的东西,我之前一直使用 C 和 C++ 代码和 pthread,但是在阅读了 Apple 的关于从线程迁移的文档之后,我决定尝试 GCD ,objective-c 太麻烦了,我不知道如何释放它NSData *pData
,NSURLResponse *pResponse
因为每当我这样做时它都会崩溃。
请指教...真的需要帮助来学习和欣赏objective-c ...
附加编辑:
感谢@robhayward,我将 pImg 和 pDataPng 作为 __block 变量放在外面,使用他的 RHCacheImageView 下载数据的方式( NSData initWithContentOfURL )
还要感谢@JorisKluivers,第一个 UIImage 实际上可以重复使用以显示 UIImageView 识别 jpg 和 png 格式,只是我以后的处理需要 png 格式,我稍后会在需要时从磁盘读取