CaptainStiggz
CaptainStiggz

Reputation: 1907

Calling AFNetworking in NSTimer causes serious memory leak

I'm trying to debug a difficult memory leak. In MyAppDelegate.m, I have

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.notificationTimer = [NSTimer scheduledTimerWithTimeInterval:1
                                                              target:self
                                                            selector:@selector(syncNotifications:)
                                                            userInfo:nil
                                                             repeats:YES];
    return YES;
}

- (void)syncNotifications:(NSTimer*)timer {
    NSString *path = @"http://example";
    NSLog(@"GET: %@", path);
    AFHTTPRequestOperationManager *network = [AFHTTPRequestOperationManager manager];
    [network GET:path parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"get success");
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];
}

I see memory leaking at the rate of ~1MB / 3 seconds. I've tried setting the network to a property. Also tried commenting out the actual network request as follows:

- (void)syncNotifications:(NSTimer*)timer {
    NSString *path = @"http://example";
    NSLog(@"GET: %@", path);
    AFHTTPRequestOperationManager *network = [AFHTTPRequestOperationManager manager];
}

And while I don't see as much memory leaked, I do still see memory allocations climbing in the Instruments panel. Am I missing something when it comes to memory management for NSTimers?

Upvotes: 0

Views: 427

Answers (2)

CaptainStiggz
CaptainStiggz

Reputation: 1907

After a lot of testing, I found that the "problem" seemed to be with AFHTTPRequestOperation. I didn't see any "leaks" when switching to the AFHTTPSessionManager.

For more information see: https://github.com/AFNetworking/AFNetworking/issues/2596

Upvotes: 0

Johannes Fahrenkrug
Johannes Fahrenkrug

Reputation: 44808

The problem is that you are creating a new instance of AFHTTPRequestOperationManager every second. The implementation of the manager method looks like this:

+ (instancetype)manager {
    return [[self alloc] initWithBaseURL:nil];
}

So if you create the manager once and hold on to it you should be able to fix your memory leak.

Upvotes: 2

Related Questions