可达性阻止dealloc被调用

时间:2015-11-26 10:05:30

标签: objective-c

我使用Reachability来检查互联网连接,但我发现我正在使用的方法阻止调用dealloc。这是我正在使用的代码:

- (void)testInternetConnection
{
    internetReachableFoo = [Reachability reachabilityWithHostname:@"www.google.com"];

    // Internet is reachable
    internetReachableFoo.reachableBlock = ^(Reachability*reach)
    {
        // Update the UI on the main thread
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"Connessione ad Internet disponibile");
            _checkConnection = YES;

        });
    };

    // Internet is not reachable
    internetReachableFoo.unreachableBlock = ^(Reachability*reach)
    {
        // Update the UI on the main thread
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"Connessione ad Internet non disponibile");
            _checkConnection = NO;
        });
    };

    [internetReachableFoo startNotifier];
}

为了调用它,我在[self testInternetConnection];内使用viewDidLoad。 问题与我在头文件中声明的bool _checkConnection有关:

@property (nonatomic, assign) BOOL checkConnection; 如果我从方法中删除了dealloc被调用,我该怎么做才能解决这个问题?

2 个答案:

答案 0 :(得分:3)

您通过引用块中的实例变量而导致保留周期。

解决方案1 ​​

在块中使用弱指针。

__weak typeof(self) weakSelf = self;

internetReachableFoo.reachableBlock = ^(Reachability*reach)
{
    // Update the UI on the main thread
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"Connessione ad Internet disponibile");
        weakSelf.checkConnection = YES;

    });
};

解决方案2

不是拥有Reachability类的本地实例,而是在应用程序处于活动状态时使其成为活动的单例。当可达性事件触发时,让它定期发送NSNotification。这允许在应用程序的任何位置使用单个可访问性对象,并且在内存管理方面通知更容易处理。

答案 1 :(得分:1)

简单易用的解决方案:将代码移至通知处理方法并以这种方式更正代码:

// set the blocks
    self.internetReachable.reachableBlock = ^(Reachability*reach)
    {
        NSLog(@"REACHABLE!");
^{internetActive=YES;});
    };

    self.internetReachable.unreachableBlock = ^(Reachability*reach)
    {
        NSLog(@"UNREACHABLE!");
    };

    // start the notifier 
    [self.internetReachable startNotifier];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil];

然后添加checkNetworkStatus方法。

- (void) checkNetworkStatus:(NSNotification *)notice
{
    // called after network status changes

    NetworkStatus internetStatus = [self.internetReachable currentReachabilityStatus];

    switch (internetStatus)

    {
        case NotReachable:
        {
            NSLog(@"The internet is down.");
            self.internetActive = NO;
            self.wifiActive=NO;
            break;

        }
        case ReachableViaWiFi:
        {
            NSLog(@"The internet is working via WIFI.");
            self.internetActive = YES;
            self.wifiActive=YES;
            }
            break;

        }
        case ReachableViaWWAN:
        {
            NSLog(@"The internet is working via WWAN.");
            self.internetActive = YES;
            self.wifiActive=NO;
            break;
        }
    }
}