我在我的非弧形项目中使用苹果的Reachabiliry课程。当我用仪器运行它来查找内存泄漏时,它引用了Reachability方法。以下是问题所在:
+ (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;
}泄漏的对象是可达性和returnValue。我知道SCNetworkReachabilityCreateWithAddress创建了一个新实例,我必须使用CFRelease,但是它发生在dealloc中!
- (void)dealloc
{
[self stopNotifier];
if (reachabilityRef != NULL)
{
CFRelease(reachabilityRef);
}
[super dealloc];
}那么,我能做些什么来避免内存泄漏呢?
UPD:也许问题在于如何调用可达性?我使用这种方法:
+ (instancetype)reachabilityForInternetConnection;
{
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
return [self reachabilityWithAddress:&zeroAddress];
}然后我就这样叫Reachability:
[[Reachability reachabilityForInternetConnection] startNotifier];不要将它分配给任何对象,只需使用这一行。我试图将这个调用更改为:
Reachability *reachability = [[Reachability reachabilityForInternetConnection] autorelease];
[reachability startNotifier];但是在这个分析器告诉我“太多的自动释放”之后。
发布于 2013-12-18 07:39:03
如果returnValue等于空可达对象泄漏,则在本例中您应该释放它。此外,根据Cocoa命名约定(ref/doc/uid/20000994-SW1),您必须返回自动释放的对象:
+ (instancetype)reachabilityWithAddress:
{
...
returnValue = [[[self alloc] init] autorelease];或者重命名要启动的方法,例如,如果您不想返回一个自动释放的对象,可以从new:newReachabilityWithAddress或类似的东西开始。
尝试在Xcode中运行静态分析器,可以帮助发现问题。
发布于 2016-02-08 16:42:43
@Alexart的答案对我有效,但是如果您想要一个简化的版本,请使用
+(instancetype)reachabilityWithAddress:(void *)hostAddress
{
SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress);
if (ref)
{
id reachability = [[self alloc] initWithReachabilityRef:CFBridgingRetain((__bridge id)ref)];
CFRelease(ref);
return reachability;
}
return nil;}
发布于 2015-10-19 13:19:34
我认为更好的做法是:
+ (Reachability*) reachabilityWithHostName: (NSString*) hostName;
{
Reachability* retVal = NULL;
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
if(reachability!= NULL)
{
retVal= [[self alloc] init];
if(retVal!= NULL)
{
retVal->reachabilityRef = reachability;
retVal->localWiFiRef = NO;
}
else
{
CFRelease(reachability);
}
}
return retVal;
}https://stackoverflow.com/questions/20652033
复制相似问题