Mar*_*ria 6 xcode memory-leaks objective-c reachability ios
我在非弧项目中使用了苹果的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;
}
Run Code Online (Sandbox Code Playgroud)
泄漏的对象是可达性和returnValue.我知道SCNetworkReachabilityCreateWithAddress创建了一个新实例,我必须CFRelease它,但它发生在dealloc!
- (void)dealloc
{
[self stopNotifier];
if (reachabilityRef != NULL)
{
CFRelease(reachabilityRef);
}
[super dealloc];
}
Run Code Online (Sandbox Code Playgroud)
那么我该怎么做才能避免内存泄漏呢?
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];
}
Run Code Online (Sandbox Code Playgroud)
然后我打电话给Reachability:
[[Reachability reachabilityForInternetConnection] startNotifier];
Run Code Online (Sandbox Code Playgroud)
并且不要将它分配给任何对象,只需使用此行.我试图将此调用更改为:
Reachability *reachability = [[Reachability reachabilityForInternetConnection] autorelease];
[reachability startNotifier];
Run Code Online (Sandbox Code Playgroud)
但在此分析仪告诉我"太多自动释放"之后.
@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;
Run Code Online (Sandbox Code Playgroud)
}
小智 7
我认为下一步做得更好:
+ (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;
}
Run Code Online (Sandbox Code Playgroud)
如果 returnValue 等于 NULL 可达性对象泄漏,在这种情况下您应该释放它。另外,根据Cocoa命名约定(https://developer.apple.com/library/ios/documentation/cocoa/conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-SW1),您必须返回autoreleased目的:
+ (instancetype)reachabilityWithAddress:
{
...
returnValue = [[[self alloc] init] autorelease];
Run Code Online (Sandbox Code Playgroud)
newReachabilityWithAddress或者,如果您不想返回自动释放的对象,则将方法重命名为从 new: 开始,或者类似的名称。
尝试在Xcode中运行静态分析器,它可以帮助发现问题。
| 归档时间: |
|
| 查看次数: |
3267 次 |
| 最近记录: |