Apple's reachability memory leak

ios, memory-leaks, objective-c, reachability, xcode

Solution

If returnValue equals to NULL reachability object is leaked, you should release it in this case. Also by Cocoa naming convention (https://developer.apple.com/library/ios/documentation/cocoa/conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-SW1) 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.

Problem

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) { CFRelease(reachabilityRef); } [super dealloc]; } ``` So what can I do to avoid memory leak here? UPD: 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".

Original source