AFHTTPSessionManager does not free

Update

After publishing this question in the AFNetworking repository, it turns out that this is actually a problem of use on my part. In response to my problem:

NSURLSession saves its delegate (i.e. AFURLSessionManager). Call invalidateSessionCancelingTasks: to ensure completion and release of its delegates.

So, a long story: if you use the AHTTPSessionManager in the manner described below, be sure to call invalidateSessionCancelingTasks: to make sure the sessions end and free the delegate.

Original question

I have subclasses of AFHTTPSessionManager called GTAPIClient that I use to connect to my REST API. I understand that the state of docs is used as a singleton, but there are several cases where I need to create a new instance. However, it seems that whenever I do this, the object is never freed. Currently, GTAPIClient literally does nothing but NSLog itself when released. Here is a sample code demonstrating the behavior

GTAPIClient.m

 @implementation GTAPIClient - (void)dealloc { NSLog(@"Dealloc: %@", self); } @end 

GTViewController.m

 #import "GTBaseEntityViewController.h" //Models #import "GTBaseEntity.h" //Clients #import "GTAPIClient.h" @interface GTBaseEntityViewController () @property (nonatomic, weak) GTAPIClient *client; @property (nonatomic, weak) GTBaseEntity *weakEntity; @end @implementation GTBaseEntityViewController - (IBAction)makeClient:(id)sender { self.client = [[GTAPIClient alloc] init]; NSLog(@"I just made an API client %@", self.client); //Another random object assigned to a similar property, just to see what happens. self.weakEntity = [[GTBaseEntity alloc] init]; NSLog(@"I just made a random object %@", self.weakEntity); } - (IBAction)checkClient:(id)sender { NSLog(@"Client: %@", self.client); NSLog(@"Entity: %@", self.weakEntity); } @end 

NSLog output

Fire makeClient:

 //It seems to me that both NSLog should return (null) as they are assigning to a weak property 2014-06-22 16:41:39.143 I just made an API client <GTAPIClient: 0x10b913680, baseURL: (null), session: <__NSCFURLSession: 0x10b915010>, operationQueue: <NSOperationQueue: 0x10b9148a0>{name = 'NSOperationQueue 0x10b9148a0'}> 2014-06-22 16:41:39.144 I just made a random object (null) 

Fire checkClient

 //Again, both NSLog should return null for the two objects. However...client is still around. Also, it overridden dealloc method never fired. 2014-06-22 16:44:43.722 Client: <GTAPIClient: 0x10b913680, baseURL: (null), session: <__NSCFURLSession: 0x10b915010>, operationQueue: <NSOperationQueue: 0x10b9148a0>{name = 'NSOperationQueue 0x10b9148a0'}> 2014-06-22 16:44:43.723 Entity: (null) 

For reference, I am using v2.3.1 AFNetworking. The compiler warns me that the assignment of the stored weak property object will be released after the assignment - this is correct and will function as expected with my random object. Nothing happens in the application. No other view controllers, no other methods in GTAPIClient , all singleton functions are removed. Any thoughts on what I'm doing wrong here?

+7
memory-management objective-c afnetworking-2
source share
3 answers

Replicating your script and running it with the tools shows that the AFURLSessionManagers are saved by the NSURLSessions they create, since the AFURLSessionManager acts as a delegate for every NSURLSession created. This creates a save loop and therefore the AFHTTPSessionManager cannot be freed. Whether this is a mistake in any library or not a mistake at all, I'm not sure. You can report this on the AFNetworking GitHub page ( https://github.com/AFNetworking/AFNetworking ).

+1
source

Posting an answer from Matt Thompson here to help future readers:

NSURLSession saves its delegate (i.e. AFURLSessionManager ). Call invalidateSessionCancelingTasks: to ensure completion and release of your delegates.

If, like many applications, your application uses a peer-to-peer session manager and one session URL for your entire application, then you need not worry about that.

+10
source
 __weak typeof(manager) weak_manager = manager; [manager requestWithMethod:method URLString: uri parameters:param success:^(NSURLSessionDataTask *task, id responseObject) { if (completion) { completion(YES, responseObject, task.response); } [weak_manager invalidateSessionCancelingTasks:YES]; } failure:^(NSURLSessionDataTask *task, NSError *error) { if (completion) { completion(NO, error, task.response); } [weak_manager invalidateSessionCancelingTasks:YES]; }]; 
0
source

All Articles