首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >苹果的可达内存泄漏

苹果的可达内存泄漏
EN

Stack Overflow用户
提问于 2013-12-18 07:27:51
回答 5查看 3.6K关注 0票数 7

我在我的非弧形项目中使用苹果的Reachabiliry课程。当我用仪器运行它来查找内存泄漏时,它引用了Reachability方法。以下是问题所在:

代码语言:javascript
复制
+ (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中!

代码语言:javascript
复制
- (void)dealloc
{
    [self stopNotifier];
    if (reachabilityRef != NULL)
    {
        CFRelease(reachabilityRef);
    }
    [super dealloc];
}

那么,我能做些什么来避免内存泄漏呢?

UPD:也许问题在于如何调用可达性?我使用这种方法:

代码语言:javascript
复制
+ (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:

代码语言:javascript
复制
[[Reachability reachabilityForInternetConnection] startNotifier];

不要将它分配给任何对象,只需使用这一行。我试图将这个调用更改为:

代码语言:javascript
复制
Reachability *reachability = [[Reachability reachabilityForInternetConnection] autorelease];
[reachability startNotifier];

但是在这个分析器告诉我“太多的自动释放”之后。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2013-12-18 07:39:03

如果returnValue等于空可达对象泄漏,则在本例中您应该释放它。此外,根据Cocoa命名约定(ref/doc/uid/20000994-SW1),您必须返回自动释放的对象:

代码语言:javascript
复制
+ (instancetype)reachabilityWithAddress:
{
    ...
     returnValue = [[[self alloc] init] autorelease];

或者重命名要启动的方法,例如,如果您不想返回一个自动释放的对象,可以从new:newReachabilityWithAddress或类似的东西开始。

尝试在Xcode中运行静态分析器,可以帮助发现问题。

票数 4
EN

Stack Overflow用户

发布于 2016-02-08 16:42:43

@Alexart的答案对我有效,但是如果您想要一个简化的版本,请使用

代码语言:javascript
复制
+(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;

}

票数 10
EN

Stack Overflow用户

发布于 2015-10-19 13:19:34

我认为更好的做法是:

代码语言:javascript
复制
+ (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;
}
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20652033

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档