将此问题作为问题发布到AFNetworking回购后,事实证明这实际上是我的使用问题。根据我的问题回复:
NSURLSession保留其委托(即AFURLSessionManager)。调用invalidateSessionCancelingTasks:确保会话最终确定并释放其委托。
所以,长话短说:如果您按照下述方式使用AHTTPSessionManager
,请务必致电invalidateSessionCancelingTasks:
以确保会话最终确定并释放其代表
我有一个名为AFHTTPSessionManager
的子类GTAPIClient
,我用它连接到我的REST API。我意识到文档声明要用作单例,但在某些情况下我需要编写一个新实例。但是,似乎每当我这样做时,对象永远不会被释放。目前,GTAPIClient
除了NSLog
本身在取消分配时几乎不执行任何操作。
这是一些演示行为的示例代码
@implementation GTAPIClient
- (void)dealloc
{
NSLog(@"Dealloc: %@", self);
}
@end
#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
开火makeClient:
//It seems to me that both NSLog's 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)
开火checkClient
//Again, both NSLog's should return null for the two objects. However...client is still around. Also, it's 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)
供参考,我使用的是AFNetworking的v2.3.1。编译器警告我,将保留对象分配给weak属性将在赋值后释放 - 这是正确的,并且随我的随机对象一起运行。应用程序中没有其他任何内容。没有其他视图控制器,GTAPIClient
上没有其他方法,所有单例功能都被删除。我在这里做错了什么想法?
答案 0 :(得分:2)
复制场景并通过Instruments运行它表明AFURLSessionManagers由他们创建的NSURLSession保留,因为AFURLSessionManager充当每个创建的NSURLSession的委托。这会创建一个保留周期,因此无法释放AFHTTPSessionManager。无论这是一个库中的错误还是根本没有错误,我都不确定。您可能希望在AFNetworking GitHub页面(https://github.com/AFNetworking/AFNetworking)上报告它。
答案 1 :(得分:1)
__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];
}];