gpt4 book ai didi

ios - NSURLConnection sendAsynchronousRequest 从不释放内存

转载 作者:行者123 更新时间:2023-11-28 19:12:28 24 4
gpt4 key购买 nike

我正在开发一个 iOS 应用程序,它可以将大量任务分派(dispatch)到我的串行队列。任务是从我的网络服务器下载图像,将其保存到磁盘,然后显示在 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_*** 和 block 的事情,我之前一直在 pthread 中使用 C 和 C++ 代码,但是在阅读了 Apple 的关于从线程迁移的文档之后,我决定给出尝试 GCD,objective-c 太麻烦了,我不确定如何释放 NSData *pDataNSURLResponse *pResponse,因为每当我这样做时它都会崩溃。

请指教...真的需要帮助来学习和欣赏 objective-c...

Profiler

附加编辑:

感谢@robhayward,我将 pImg 和 pDataPng 作为 __block 变量放在外面,使用他的 RHCacheImageView 下载数据的方式( NSData initWithContentOfURL )

还要感谢@JorisKluivers,第一个 UIImage 实际上可以重用显示,因为 UIImageView 识别 jpg 和 png 格式,只是我以后的处理需要 png 格式,我稍后会在需要时从磁盘读取

最佳答案

我首先将其归结为您正在创建的图像和数据对象:

UIImage *pImg = [UIImage imageWithData:pData];
NSData *pDataPng = UIImagePNGRepresentation(pImg);

这可能会停留太久,也许将它们放在 block 之外,因为它们可能是在不同的线程上创建/释放的:

__block UIImage *pImg = nil;
__block NSData *pDataPng = nil;
[NSURLConnection sendAsynchronousRequest..

(也可以考虑使用 ARC)

我在 Github 上有一些代码可以完成类似的工作但没有这个问题,请随时查看:

https://github.com/robinhayward/RHCache/blob/master/RHCache/RHCache/Helpers/UIImageView/RHCacheImageView.m

关于ios - NSURLConnection sendAsynchronousRequest 从不释放内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14460652/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com