As the users test my app, he random click the screen very quickly, like a monkey , to into my every detail view controller
, because every into my detail vc
, the vc
will fetch data
from the net. And in the real device my app crash
.
I think this issue is cause by memory leak
, because this did not appear in simulator
, I test my app in instrument
, the screenshoot
in below:
In instrument:
The situation:
my main screen, click the every item
on the main screen will in to a different detail vc
.
detail one vc
, every in detail vc
, user test will fetch data
or click random:
the memory grow to 90.5MB
, and did not come down, if use user's test method, if take more long time, will be more than 90.5MB
:
I use instrument
is not that well, and the memory is most used by AFNetworking
, i don't know how to do with this. Someone can give advice? Most thanks in advance.
EDIT
I make the AFHTTPSessionManager
to be a singleton
, but I found my net request become slowly, does this affect me?
#import "Mysevers.h"
#import "AFNetworking.h"
#import "HUD.h"
static AFHTTPSessionManager *requestManager ;
@implementation Mysevers
+ (AFHTTPSessionManager *)sharedHTTPSession{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
requestManager = [AFHTTPSessionManager manager];
requestManager.requestSerializer.timeoutInterval = 10;
});
return requestManager;
}
+(void)AFPOSTWithHud:(BOOL)hud andAddressname:(NSString*)addressName parmas:(NSDictionary*)parmas RequestSuccess:(void(^)(id result))success failBlcok:(void(^)(void))failBlcok
{
if (hud) {
//[HUD addHUD];
[SVProgressHUD show];
}
AFHTTPSessionManager *requestManager = [Mysevers sharedHTTPSession];
NSString *urlStr = [NSString stringWithFormat:@"%@%@",BASE_URL,addressName];
DLog(@"%@",urlStr);
[requestManager POST:urlStr parameters:parmas progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (hud) {
//[HUD removeHUD];
[SVProgressHUD dismiss];
}
success(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (error != nil) {
DLog(@"error==%@",[error localizedDescription]);
if (hud) {
//[HUD removeHUD];
[SVProgressHUD dismiss];
}
failBlcok();
}
return ;
}];
}
+(void)AFGETWithHud:(BOOL)hud andAddressname:(NSString*)addressName parmas:(NSDictionary*)parmas RequestSuccess:(void(^)(id result))success failBlcok:( void(^)(void))failBlcok
{
if (hud) {
//[HUD addHUD];
[SVProgressHUD show];
}
AFHTTPSessionManager *requestManager = [Mysevers sharedHTTPSession];
NSString *urlStr = [NSString stringWithFormat:@"%@%@",BASE_URL,addressName];
DLog(@"%@",urlStr);
[requestManager GET:urlStr parameters:parmas progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (hud) {
//[HUD removeHUD];
[SVProgressHUD dismiss];
}
success(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
DLog(@"error==%@",[error localizedDescription]);
if (hud) {
//[HUD removeHUD];
[SVProgressHUD dismiss];
}
failBlcok();
}];
}
@end
You'll see this behavior if you are instantiating lots of new NSURLSession
objects (i.e. which will happen if you instantiate a lot of AFHTTPSessionManager
objects).
For example, I wrote a simple program that instantiated 50 separate NSURLSession
objects, did a simple data task for each (designated by a "sign post" under the "points of interest", below, all taking place during the region indicated by the green bar), and then immediately releasing them.
You'll see that memory went up by almost 6mb, but after roughly 2 minutes (with absolutely no intervention on my part), it only started reclaiming that memory, returning more than half of the memory previously consumed by all of those session objects. This is a reproducible pattern that I see when issuing multiple session objects.
This can be solved by either calling finishTasksAndInvalidate
on the NSURLSession
objects, or, better, by making sure your app instantiates only one session object and then uses that same session object every time. Either one of these approaches will dramatically reduce the memory profile of the app (and reusing the same session object is simply more efficient).
In short, I would ensure your detail view controller is not instantiating a new AFHTTPSessionManager
object each time. Instantiate it once in your app and reuse it.
Having said that, I wonder if you might also have some other memory problem as my 50 NSURLSession
objects only consumed 6mb of memory, and it sounds like you're losing more than that. So, I'd suggest fixing the above, but if you're still seeing memory consumption going up (not necessary shown in Leaks anymore, though), perhaps you have some strong reference cycle or the like. The Xcode 8 "debug memory graph" tool (see How to debug memory leaks when Leaks instrument does not show them?) can be helpful in tracking those issues down.