Sam*_*io2 8 recursion memory-leaks objective-c ios nsurlsession
我的代码中存在内存泄漏问题,我需要快速连续获取许多URL,每个GET都受到前一个GET结果的影响.目的是在响应中查找特定内容.
我发现最简洁的方法是递归地实现它,因为我可以使用相同的方法来确定响应中是否存在所需的值.功能上它非常好用,但它会泄漏内存,如下所述.我也以迭代的方式实现了相同的功能,这也泄漏了内存.
在我看来,似乎NSURLSession
API负责泄漏这个内存,它只发生在很快连续多次调用时.但是,如果有人能指出我正在犯的任何明显错误,我将不胜感激.
2014年9月14日更新:
更新以添加递归计数器,即使代码未执行无限次,也可以证明泄漏仍然存在.还略微整理了实现,在视图控制器中重新使用NSURLSession
和NSURLSessionConfiguration
作为属性.
示例代码:
- (void)performURLCallRecursive {
recursionLimiter++;
if (recursionLimiter > 10) {
[self.session finishTasksAndInvalidate];
return;
}
NSURL * checkURL = [NSURL URLWithString:@"http://www.google.com"];
__block NSMutableURLRequest * urlRequest = [[NSMutableURLRequest alloc] initWithURL:checkURL
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:0.0f];
__weak typeof(self) weakSelf = self;
NSURLSessionDataTask * task = [self.session dataTaskWithRequest:urlRequest
completionHandler:^(NSData *data, NSURLResponse *response, NSError
*error) {
NSString * body = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"Body: %@", body);
[weakSelf performURLCallRecursive];
}];
[task resume];
}
#pragma mark - Getters
- (NSURLSessionConfiguration *)sessionConfiguration {
if (!_sessionConfiguration) {
_sessionConfiguration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
[_sessionConfiguration setAllowsCellularAccess:NO];
[_sessionConfiguration setTimeoutIntervalForRequest:10.0f];
[_sessionConfiguration setTimeoutIntervalForResource:10.0f];
[_sessionConfiguration setURLCache:[[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil]];
}
return _sessionConfiguration;
}
- (NSURLSession *)session {
if (_session == nil) {
_session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration
delegate:[SPRSessionDelegate new]
delegateQueue:nil];
}
return _session;
}
Run Code Online (Sandbox Code Playgroud)
仪器报告的内存泄漏.(注意:这些每次都略有不同,但大多数情况下包含相同的泄漏,只是或多或少相同的泄漏):
进一步更新:
所以,我实际上迭代地实现了相同的代码,并且仍然发生内存泄漏.对于这个例子,我包含了一个循环限制器,因此它永远不会执行.任何人都可以帮我弄清楚这里到底发生了什么?
- (void)performURLCallIterative
{
int loopLimiter = 0;
do {
NSURLSessionConfiguration * defaultSession = [NSURLSessionConfiguration defaultSessionConfiguration];
[defaultSession setAllowsCellularAccess:NO];
[defaultSession setTimeoutIntervalForRequest:10.0f];
[defaultSession setTimeoutIntervalForResource:10.0f];
NSURLSession * session = [NSURLSession sessionWithConfiguration:defaultSession
delegate:self
delegateQueue:nil];
NSURL * checkURL = [NSURL URLWithString:@"http://google.com"];
NSMutableURLRequest * urlRequest = [[NSMutableURLRequest alloc] initWithURL:checkURL
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:0.0f];
__weak NSURLSession * weakSession = session;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
NSURLSessionDataTask * task = [session dataTaskWithRequest:urlRequest
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString * body = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"Body: %@", body);
dispatch_semaphore_signal(semaphore);
[weakSession invalidateAndCancel];
}];
[task resume];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
loopLimiter++;
} while (loopLimiter <= 6);
}
Run Code Online (Sandbox Code Playgroud)
2014年9月14日更新:
对于可能在这里找到自己的方式的任何Google员工,iOS 8上仍然会出现这种情况.就我而言,这是iOS中的一个错误.
归档时间: |
|
查看次数: |
2656 次 |
最近记录: |