Maria Maria - 7 months ago 61
iOS Question

Apple's reachability memory leak

I use apple's Reachabiliry class in my non-arc project. And when I run it with instruments to find memory leaks, it referes to Reachability method. Here is the problem:

+ (instancetype)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress;
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)hostAddress);

WReachability* returnValue = NULL;

if (reachability != NULL)
returnValue = [[self alloc] init];
if (returnValue != NULL)
returnValue->reachabilityRef = reachability;
returnValue->localWiFiRef = NO;
return returnValue;

The leaked objects are reachability and returnValue.
I understand that SCNetworkReachabilityCreateWithAddress creates a new instance and I must CFRelease it, but it happens right in dealloc!

- (void)dealloc
[self stopNotifier];
if (reachabilityRef != NULL)
[super dealloc];

So what can I do to avoid memory leak here?

Maybe the problem is in how reachability get called? I use this method:

+ (instancetype)reachabilityForInternetConnection;
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;

return [self reachabilityWithAddress:&zeroAddress];

Then I called Reachability like this:

[[Reachability reachabilityForInternetConnection] startNotifier];

And don't assign it to any object, just use this line.
I've tried to change this calls to something like:

Reachability *reachability = [[Reachability reachabilityForInternetConnection] autorelease];
[reachability startNotifier];

But after this analyzer told me "too many autorelease".


If returnValue equals to NULL reachability object is leaked, you should release it in this case. Also by Cocoa naming convention ( you must return autoreleased object:

+ (instancetype)reachabilityWithAddress:
     returnValue = [[[self alloc] init] autorelease];

Or rename the method to start for example from new: newReachabilityWithAddress or something like this if you don't want to return an autoreleased object.

Try to run static analyser in Xcode, it can help to spot the problems.