调用 Reachability startNotifier 后,Network 状态变为 0
Posted
技术标签:
【中文标题】调用 Reachability startNotifier 后,Network 状态变为 0【英文标题】:After calling Reachability startNotifier, the Network status changes to 0 【发布时间】:2013-02-13 09:39:53 【问题描述】:在我的 ios 应用程序中,我需要使用 Reachability 来完成以下任务:
-
在渲染视图控制器时,应用程序需要检查连接状态,并相应地显示连接图标图像(在线或离线)。
当用户停留在视图控制器上时,如果互联网连接状态发生变化,将通知应用程序发生变化,然后相应地执行一些任务。
我在我的应用程序中使用了由 Tony Million 生成的 Reachability 类,但是发生了一件奇怪的事情: 调用startNotified方法后,可达状态变为0(NotReachable)。
以下是我的代码:
BTLandingViewController.h
#import <UIKit/UIKit.h>
#import "MBProgressHUD.h"
#import "Reachability.h"
@interface BTLandingViewController : UIViewController <UIAlertViewDelegate>
__weak IBOutlet UIImageView *internetIndicator;
MBProgressHUD *hud;
Reachability *reach;
UIAlertView *emptyRecordsAlert;
UIAlertView *syncReminderAlert;
@end
部分代码在 BTLandingViewController.m
#import "BTLandingViewController.h"
@interface BTLandingViewController ()
@end
@implementation BTLandingViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
// Initialize reachability
reach = [Reachability reachabilityWithHostname:BTReachTestURL];
return self;
- (void)viewDidAppear:(BOOL)animated
[super viewDidAppear:animated];
// Register with reachability changed notification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reachabilityChanged:)
name:kReachabilityChangedNotification
object:nil];
NetworkStatus internetStatus = [reach currentReachabilityStatus]; // value = 1 or 2
***// PS: If there is connection, before [reach startNotifier], the internetStatus's value reflects the connection status (1 or 2)***
// Start notify reachability change
[reach startNotifier];
internetStatus = [reach currentReachabilityStatus]; // Value = 0;
***// PS: Even if there is connection, after [reach startNotifier], the internetStatus's value becomes 0***
感谢您的帮助。
【问题讨论】:
你有没有关注苹果提供的可达性示例 已在代码中编辑您的帖子,必须先设置通知中心,然后再设置通知中心 您在项目中使用 ARC 吗?如果没有,我猜你必须保留 Reachability 对象。我在很多项目中都使用了 Reachability,但从来没有遇到过这样的问题。而且,是的,正如@Vinodh 建议的那样,您必须在启动通知程序之前注册通知。祝你好运! 谢谢大家,但问题仍然存在。我正在使用由 Tony Million 创建的 ARC 兼容版本的可达性。在通知中心注册后,我已经更改了启动通知程序。请检查我的代码。但是即使有互联网连接,调用 startNotifier 后网络状态仍然会变为 0。 【参考方案1】:我终于通过解决上面提到的 startNotifier 陷阱解决了这个问题。调用 startNotifier 确实将网络状态更改为 0,但我声明了一个变量来存储视图控制器呈现时的初始网络状态。然后在处理由reachabilityChanged通知触发的动作的方法中的if语句中使用变量的值。以下是我的代码:
BTLandingViewController.h
#import <UIKit/UIKit.h>
#import "MBProgressHUD.h"
#import "Reachability.h"
@interface BTLandingViewController : UIViewController <UIAlertViewDelegate>
__weak IBOutlet UIImageView *internetIndicator;
MBProgressHUD *hud;
NSInteger initialNetworkStatus;
UIAlertView *emptyRecordsAlert;
UIAlertView *syncReminderAlert;
@end
BTLandingViewController.m
#import "BTLandingViewController.h"
#import "BTSyncEngine.h"
#import "BTInstructorLoginViewController.h"
#import "BTGlobalParams.h"
@interface BTLandingViewController ()
@end
@implementation BTLandingViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
return self;
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
- (void)viewDidUnload
internetIndicator = nil;
[super viewDidUnload];
- (void)viewDidAppear:(BOOL)animated
[super viewDidAppear:animated];
// Register with sync complete notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(syncCompleted:) name:@"BTSyncEngineSyncCompleted" object:nil];
// Register with reachability changed notification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reachabilityChanged:)
name:kReachabilityChangedNotification
object:nil];
Reachability *reach = [Reachability reachabilityWithHostname:BTReachTestURL];
reach.reachableBlock = ^(Reachability * reachability)
dispatch_async(dispatch_get_main_queue(), ^
initialNetworkStatus = 1;
[internetIndicator setImage:[UIImage imageNamed:@"online_indicator.png"]];
// Start syncing local records with the remote server
[[BTSyncEngine sharedEngine] startSync];
hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = @"Sync in progress";
);
;
reach.unreachableBlock = ^(Reachability * reachability)
dispatch_async(dispatch_get_main_queue(), ^
initialNetworkStatus = 0;
[internetIndicator setImage:[UIImage imageNamed:@"offline_indicator.png"]];
// If the initial sync has been executed
// then use the cached records on the device
if ([[BTSyncEngine sharedEngine] initialSyncComplete])
// Go to instructor login screen
BTInstructorLoginViewController *instructorLoginViewController = [[BTInstructorLoginViewController alloc] init];
[instructorLoginViewController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentViewController:instructorLoginViewController animated:YES completion:nil];
// If the initial sync has not been executed
// show an alert view
else
emptyRecordsAlert = [[UIAlertView alloc] initWithTitle:@"Alert" message:@"Please connect to the internet to load data for the first time use." delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
[emptyRecordsAlert show];
);
;
[reach startNotifier];
- (void)viewDidDisappear:(BOOL)animated
[super viewDidDisappear:animated];
// Unregister with reachability changed notification
[[NSNotificationCenter defaultCenter] removeObserver:self name:kReachabilityChangedNotification object:nil];
// Unregister with sync complete notification
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"BTSyncEngineSyncCompleted" object:nil];
- (void)syncCompleted:(NSNotification *)note
// Update the global sync completed flag
[[BTGlobalParams sharedParams] setSyncCompleted:YES];
// Hide syncing indicator
[MBProgressHUD hideHUDForView:self.view animated:YES];
// Go to instructor login screen
BTInstructorLoginViewController *instructorLoginViewController = [[BTInstructorLoginViewController alloc] init];
[instructorLoginViewController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentViewController:instructorLoginViewController animated:YES completion:nil];
- (void)reachabilityChanged:(NSNotification *)note
Reachability *reach = [note object];
if ([reach isReachable] && !initialNetworkStatus)
[internetIndicator setImage:[UIImage imageNamed:@"online_indicator.png"]];
// Start syncing local records with the remote server
[[BTSyncEngine sharedEngine] startSync];
hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = @"Sync in progress";
@end
【讨论】:
以上是关于调用 Reachability startNotifier 后,Network 状态变为 0的主要内容,如果未能解决你的问题,请参考以下文章