我通过仪器运行我的应用程序,看看是否有任何内存泄漏。我注意到有两个漏洞出现了。一次泄漏只发生在启动时,这是:
第4行是代码中令人讨厌的代码:
static id (*_old_UIStoryboard_instantiateViewControllerWithIdentifier_)(UIStoryboard *self, SEL _cmd, NSString *identifier);
static id _UIStoryboard_instantiateViewControllerWithIdentifier_(UIStoryboard *self, SEL _cmd, NSString *identifier)
{
id ret = _old_UIStoryboard_instantiateViewControllerWithIdentifier_(self, _cmd, identifier);
if ([[self delegate] respondsToSelector:@selector(storyboard:didInstantiateViewController:withIdentifier:)])
[[self delegate] storyboard:self didInstantiateViewController:ret withIdentifier:identifier];
return ret;
}
我遇到的最大漏洞实际上是AFNetworking
代码。我不确定我所做的事情是否会导致它。在类文件中:AFURLSessionManager.m
- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration {
self = [super init];
if (!self) {
return nil;
}
if (!configuration) {
configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
}
self.sessionConfiguration = configuration;
self.operationQueue = [[NSOperationQueue alloc] init];
self.operationQueue.maxConcurrentOperationCount = 1;
self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];
self.responseSerializer = [AFJSONResponseSerializer serializer];
self.securityPolicy = [AFSecurityPolicy defaultPolicy];
self.reachabilityManager = [AFNetworkReachabilityManager sharedManager];
self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init];
self.lock = [[NSLock alloc] init];
self.lock.name = AFURLSessionManagerLockName;
[self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
for (NSURLSessionDataTask *task in dataTasks) {
[self addDelegateForDataTask:task completionHandler:nil];
}
for (NSURLSessionUploadTask *uploadTask in uploadTasks) {
[self addDelegateForUploadTask:uploadTask progress:nil completionHandler:nil];
}
for (NSURLSessionDownloadTask *downloadTask in downloadTasks) {
[self addDelegateForDownloadTask:downloadTask progress:nil destination:nil completionHandler:nil];
}
}];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidResume:) name:AFNSURLSessionTaskDidResumeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidSuspend:) name:AFNSURLSessionTaskDidSuspendNotification object:nil];
return self;
}
上述方法中的这些行显示为泄漏内存 - 每次调用此方法时:
if (!configuration) {
configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
}
self.operationQueue = [[NSOperationQueue alloc] init];
更糟糕的是泄漏次数最多:
self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];
而且:
self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init];
然后是最后一个:
self.securityPolicy = [AFSecurityPolicy defaultPolicy];
我该如何解决这些泄漏?另外,我想知道他们为什么泄漏记忆而不仅仅是解决方案,想了解更多关于这些案例的信息。
答案 0 :(得分:0)
尝试在块中使用weak_self,而不是self,例如:
__weak ClassName *weak_self = self;
[self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
for (NSURLSessionDataTask *task in dataTasks) {
[weak_self addDelegateForDataTask:task completionHandler:nil];
}
for (NSURLSessionUploadTask *uploadTask in uploadTasks) {
[weak_self addDelegateForUploadTask:uploadTask progress:nil completionHandler:nil];
}
for (NSURLSessionDownloadTask *downloadTask in downloadTasks) {
[weak_self addDelegateForDownloadTask:downloadTask progress:nil destination:nil completionHandler:nil];
}
}];