gpt4 book ai didi

iOS NSURLConnection (sendAsynchronousRequest :) too much cache

转载 作者:塔克拉玛干 更新时间:2023-11-02 10:02:38 27 4
gpt4 key购买 nike

我的应用程序中有几个内存泄漏(不!请参阅更新 1),它们都归结为异步 URLRequest。下面的代码给了我一个内存泄漏,似乎“数据”从未被释放(下面的代码在逻辑上没有在我的应用程序中使用,因为它是一个完全无用的无限循环,我只是写它来显示内存泄漏。这个使使用的 RAM 在不到一秒内从 5 MB 增加到 20 MB。我的网速确实符合这个 [仅作记录]):

- (void)start{
NSOperationQueue *oQC = [[NSOperationQueue alloc] init];
NSLog(@"a");
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.online-image-editor.com//styles/2014/images/example_image.png"]] queue:oQC completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSLog(@"b");
[self start];
}];
}

我也试过设置 data = nil,但是,就像假设的那样,不起作用。是否有人知道如何避免内存泄漏以及这是否是 NSURLConnection 的正常行为?

更新 1:

这似乎与内存泄漏无关,而是与缓存问题有关。 (感谢@rdelmar,他看到了问题,但他的解决方案并不奏效)

基于 this post我尝试在它的 .h 文件中创建一个新的“Loader”类:

#import <Foundation/Foundation.h>

@interface Loader : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate>

@property NSMutableData *mData;
@property (nonatomic, copy) void (^returnBlock)(NSData *data, NSError *error);

- (id)initForWhateverWithURLString:(NSString*)urlString andHandler:(void (^)(NSData *data, NSError *error))handler;

@end

这是 .m 文件中的内容:

#import "Loader.h"

@implementation Loader

@synthesize mData;

- (id)initForWhateverWithURLString:(NSString*)urlString andHandler:(void (^)(NSData *data, NSError *error))handler{
self = [super init];
if (self) {
/*NSOperationQueue *oQC = [NSOperationQueue mainQueue];
[NSURLConnection sendAsynchronousRequest:mUR queue:oQC completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
[[NSURLCache sharedURLCache] removeCachedResponseForRequest:mUR];
handler(nil, nil);
}];*/
mData = [NSMutableData new];
self.returnBlock = handler;
NSMutableURLRequest *mUR = [[NSURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60] mutableCopy];
NSURLConnection *URLCon = [[NSURLConnection alloc] initWithRequest:mUR delegate:self];
[URLCon start];
}
return self;
}

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse{
return nil;
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[mData appendData:data];
data = nil;
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
self.returnBlock(mData, nil);
mData = nil;
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
self.returnBlock(nil, error);
}

@end

我还实现了:

NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:@"nsurlcache"];
[NSURLCache setSharedURLCache:sharedCache];

尽管如此,这些方法都无法帮助减少急剧的 RAM 使用量!

最佳答案

我不认为你看到的是泄漏。我认为内存不断增加,因为正在缓存数据。如果您更改请求的缓存协议(protocol),问题就会消失(您将获得默认行为,NSURLRequestUseProtocolCachePolicy,通过使用 requestWithURL:)

- (void)viewDidLoad {
[super viewDidLoad];
self.req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.online-image-editor.com//styles/2014/images/example_image.png"] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10];
[self start];
}

- (void)start{
NSOperationQueue *oQC = [NSOperationQueue mainQueue]; // this queue is where the completion block runs, so you should use mainQueue if you want to do any UI updating
NSLog(@"a");
[NSURLConnection sendAsynchronousRequest:self.req queue:oQC completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSLog(@"b");
[self start];
}];
}

编辑后:

在进一步查看之后,我不确定为什么 sendAsynchronousRequest: 会导致内存使用量随时间增加。我使用 NSURLSession(无论如何我们现在应该使用它)进行了测试,这似乎没有导致内存增加。

- (void)viewDidLoad {
[super viewDidLoad];
NSString *urlString = @"http://www.online-image-editor.com//styles/2014/images/example_image.png";
self.req = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10];
[self start];
}

- (void)start{
NSLog(@"a");
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionDataTask *task = [session dataTaskWithRequest:self.req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
self.counter ++;
NSLog(@"counter is: %ld", self.counter);
[self start];
}];
[task resume];
}

关于iOS NSURLConnection (sendAsynchronousRequest :) too much cache,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27678865/

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