我找不到这段代码中的错误:
-(void)downloadImageFromURL:(NSURL*)url withCompletionBlock:(RSSMessageImageDownloadCompletionBlock)completionBlock
{
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
__block RSSMessage *_self = self;
request.completionBlock =
^{
__block NSData *responseData = request.responseData;
dispatch_async( dispatch_get_main_queue(), ^{
_self.image = responseData;
[[[UIApplication sharedApplication] delegate] saveContext];
if(completionBlock != nil)
{
completionBlock();
}
});
};
[request startAsynchronous];
}
在这种形式下,我遇到了仪器内存泄漏的情况。我假设这是因为我之前缺少 __block 关键字:ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
但是,当我将此关键字添加到上面一行时,出现如下错误:
* -[NSConcreteMutableData isNSData__]: message sent to deallocated instance 0xdeab380
我不知道如何保留请求数据而不泄漏内存。
最佳答案
我对这个库一无所知,所以你可能应该在这方面听取维京人的建议。
但是,我可以帮助您解决泄漏,这是在 block 和请求对象之间创建的保留循环的结果。具体来说,请注意您的 request
对象持有对代码块对象的强引用(通过 request.completionBlock
)。
反过来,您的代码块对象持有对 request
的强引用,因为它访问 request.responseData
。此外,请注意,您的代码看起来很可能是 ARC,但这并不能解释您的 _self
变量构造,它看起来像是非 ARC 弱引用。非 ARC __block 没有保留对象。在 ARC 下,__block 确实会导致保留。
假设使用 ARC,我建议进行以下更改。
-(void)downloadImageFromURL:(NSURL*)url withCompletionBlock (RSSMessageImageDownloadCompletionBlock)completionBlock
{
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
__weak ASIHTTPRequest *weakRequest = request;
__weak RSSMessage *weakSelf = self;
request.completionBlock = ^{
NSData *responseData = weakRequest.responseData;
// Check for nil if not ok with nil data
dispatch_async( dispatch_get_main_queue(), ^{
weakSelf.image = responseData;
[[[UIApplication sharedApplication] delegate] saveContext];
if(completionBlock != nil)
{
completionBlock();
}
});
};
[request startAsynchronous];
}
现在,完成 block 持有对响应对象的弱引用,这打破了保留循环。请注意,一般来说,您应该创建对弱引用的本地强引用,以确保该对象停留足够长的时间来完成其工作。但是,在这种特定情况下,似乎没有必要。我认为没有图像是可以的。
关于objective-c - ASIHTTPRequest block 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12079251/