NSURLSession Speicherverluste auftreten, wenn mithilfe von web-services in IOS
Baue ich eine app verwendet einen web-service und Informationen erhalten können, die web-service, den ich verwenden NSURLSession
und NSURLSessionDataTask
.
Ich bin jetzt in der Erinnerung der Testphase, und ich habe festgestellt, dass NSURLSession
verursachen Speicherverluste.
Dies ist nicht alle Lecks. Es ist alles, ich könnte passen in das Bild.
Unten ist, wie richte ich das NSURLSession
und fordern Sie die Informationen aus den web-service.
#pragma mark - Getter Methods
- (NSURLSessionConfiguration *)sessionConfiguration
{
if (_sessionConfiguration == nil)
{
_sessionConfiguration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
[_sessionConfiguration setHTTPAdditionalHeaders:@{@"Accept": @"application/json"}];
_sessionConfiguration.timeoutIntervalForRequest = 60.0;
_sessionConfiguration.timeoutIntervalForResource = 120.0;
_sessionConfiguration.HTTPMaximumConnectionsPerHost = 1;
}
return _sessionConfiguration;
}
- (NSURLSession *)session
{
if (_session == nil)
{
_session = [NSURLSession
sessionWithConfiguration:self.sessionConfiguration
delegate:self
delegateQueue:[NSOperationQueue mainQueue]];
}
return _session;
}
#pragma mark -
#pragma mark - Data Task
- (void)photoDataTaskWithRequest:(NSURLRequest *)theRequest
{
#ifdef DEBUG
NSLog(@"[GPPhotoRequest] Photo Request Data Task Set");
#endif
//Remove existing data, if any
if (_photoData)
{
[self setPhotoData:nil];
}
self.photoDataTask = [self.session dataTaskWithRequest:theRequest];
[self.photoDataTask resume];
}
#pragma mark -
#pragma mark - Session
- (void)beginPhotoRequestWithReference:(NSString *)aReference
{
#ifdef DEBUG
NSLog(@"[GPPhotoRequest] Fetching Photo Data...");
#endif
_photoReference = aReference;
NSString * serviceURLString = [[NSString alloc] initWithFormat:@"%@/json?photoreference=%@", PhotoRequestBaseAPIURL, self.photoReference];
NSString * encodedServiceURLString = [serviceURLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
serviceURLString = nil;
NSURL * serviceURL = [[NSURL alloc] initWithString:encodedServiceURLString];
encodedServiceURLString = nil;
NSURLRequest * request = [[NSURLRequest alloc] initWithURL:serviceURL];
[self photoDataTaskWithRequest:request];
serviceURL = nil;
request = nil;
}
- (void)cleanupSession
{
#ifdef DEBUG
NSLog(@"[GPPhotoRequest] Session Cleaned Up");
#endif
[self setPhotoData:nil];
[self setPhotoDataTask:nil];
[self setSession:nil];
}
- (void)endSessionAndCancelTasks
{
if (_session)
{
#ifdef DEBUG
NSLog(@"[GPPhotoRequest] Session Ended and Tasks Cancelled");
#endif
[self.session invalidateAndCancel];
[self cleanupSession];
}
}
#pragma mark -
#pragma mark - NSURLSession Delegate Methods
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
#ifdef DEBUG
NSLog(@"[GPPhotoRequest] Session Completed");
#endif
if (error)
{
#ifdef DEBUG
NSLog(@"[GPPhotoRequest] Photo Request Fetch: %@", [error description]);
#endif
[self endSessionAndCancelTasks];
switch (error.code)
{
case NSURLErrorTimedOut:
{
//Post notification
[[NSNotificationCenter defaultCenter] postNotificationName:@"RequestTimedOut" object:self];
}
break;
case NSURLErrorCancelled:
{
//Post notification
[[NSNotificationCenter defaultCenter] postNotificationName:@"RequestCancelled" object:self];
}
break;
case NSURLErrorNotConnectedToInternet:
{
//Post notification
[[NSNotificationCenter defaultCenter] postNotificationName:@"NotConnectedToInternet" object:self];
}
break;
case NSURLErrorNetworkConnectionLost:
{
//Post notification
[[NSNotificationCenter defaultCenter] postNotificationName:@"NetworkConnectionLost" object:self];
}
break;
default:
{
}
break;
}
}
else {
if ([task isEqual:_photoDataTask])
{
[self parseData:self.photoData fromTask:task];
}
}
}
- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(NSError *)error
{
if (error)
{
#ifdef DEBUG
NSLog(@"[GPPhotoRequest] Session Invalidation: %@", [error description]);
#endif
}
if ([session isEqual:_session])
{
[self endSessionAndCancelTasks];
}
}
#pragma mark -
#pragma mark - NSURLSessionDataTask Delegate Methods
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
#ifdef DEBUG
NSLog(@"[GPPhotoRequest] Received Data");
#endif
if ([dataTask isEqual:_photoDataTask])
{
[self.photoData appendData:data];
}
}
#pragma mark -
Frage:
Warum ist NSURLSession
verursacht diese Speicherlecks? Ich bin entkräften die NSURLSession
wenn ich fertig bin mit ihm. Ich bin auch der Freigabe von Eigenschaften, die brauche ich nicht und Einstellung, die Sitzung zu null (siehe - (void)cleanupSession & - (void) endSessionAndCancelTasks).
Weitere Informationen:
Speicherverluste auftreten, nachdem die Sitzung abgeschlossen ist und "bereinigt". Manchmal, Sie kommen auch, nachdem ich knallte die UIViewController
. Aber alle meine custom (GPPhotoRequest und GPSearch) Objekte und UIViewController werden dealloced (ich habe dafür gesorgt, indem ein NSLog).
Habe ich versucht, nicht zu veröffentlichen, zu viel code, aber ich fühlte, wie die meisten, die es brauchte, um gesehen zu werden.
Bitte lassen Sie mich wissen, wenn Sie weitere Informationen benötigen. Hilfe ist sehr geschätzt.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hatte ich das gleiche "leaky" -, Speicher-management-Problem, wenn ich eingeschaltet, um NSURLSession. Für mich, nach dem erstellen einer Sitzung und fortsetzen/starten dataTask, war ich nie sagen, die Sitzung zu reinigen selbst (d.h. die Freigabe des Arbeitsspeichers zugewiesen ist).
Aus der docs:
Reinigung meiner Sitzungen behoben, durch das Speicher-Lecks berichtet wird über Instrumente.
Nach Wiederlesen der URL-Loading-System Programming Guide es stellt sich, dass ich die Einstellung der
NSURLSession
Eigenschaft auf nil zu früh.Statt, ich brauche, um die
NSURLSession
- Eigenschaft auf null, NACHDEM ich erhalten die Delegierten NachrichtURLSession:(NSURLSession *)session didBecomeInvalidWithError:(NSError *)error
, was Sinn macht. Zum Glück, es war ein kleiner Fehler.E. g.
Hatte das gleiche Problem. Die @Jonathan ' s Antwort hat keinen Sinn - meine app noch Speicherleck. Ich fand heraus, dass das setzen der session-Eigenschaft auf null im
URLSession:didBecomeInvalidWithError:
delegate-Methode, die das Problem verursacht. Versuchte sich tiefer in den URL-Loading-System Programming Guide. Es sagtVerließ ich die delegate-Methode leer. Aber der für ungültig erklärten
session
Immobilie noch über einen Zeiger, Wann sollte ich esnil
? Ich habe gerade diese Eigenschaft schwachDie app gestoppt undicht Speicher.
Bitte siehe meine Antwort hier: https://stackoverflow.com/a/53428913/4437636
Ich glaube, das Leck ist die gleiche, die ich sah, und geschieht nur, wenn Netzwerk-Verkehr über einen proxy. Mein code war in Ordnung, aber es stellte sich heraus, dass ein interner Fehler in der Apple-API wurde, verursacht das Leck.