有可达性专家吗?
我的应用程序运行得非常好,直到我将 Reachability .h 和 .m 文件合并到其中以检查互联网连接。虽然在大多数情况下,一切仍然运行得很好(所有网页都正确加载,当我故意关闭机场来测试东西时,可达性会优雅地捕获它) - 我现在确实会在奇怪的时候遇到莫名其妙的崩溃,并出现可怕的“ Exc-错误访问”错误... 我运行 Instruments 并发现了 Zombie - 请参阅屏幕截图:
查看“RefCt”列,您可以看到它达到 15 - 并且我已经看到它超过20了! 在“负责任的调用者”列(最右边)中,我看到了各种我不认识的方法 - 而且谁的调用我当然没有发起 - 我假设它们是在运行期间由系统内部调用的-时间?
不管怎样,我遵循了苹果的可达性代码和非常仔细的说明,以及来自这个排名非常高的 stackoverflow 线程的提示: 如何在 iOS 上检查活动的互联网连接或 OSX?
但我仍然遇到这些莫名其妙的崩溃。
有人可以提供任何建议吗?
这是代码:
#import "Reachability.h"
-(void) viewWillAppear:(BOOL)animated
{
// check for internet connection
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil];
internetReachable = [[Reachability reachabilityForInternetConnection] retain];
[internetReachable startNotifier];
// check if a pathway to a random host exists
hostReachable = [[Reachability reachabilityWithHostName: @"www.apple.com"] retain];
[hostReachable startNotifier];
// now patiently wait for the notification
}
-(void) viewDidLoad {
url = [NSURL URLWithString: @"http://www.google.com"];
NSURLRequest *req = [NSURLRequest requestWithURL: url];
[webPageView loadRequest:req];
[super viewDidLoad];
}
-(void) checkNetworkStatus:(NSNotification *)notice
{
// called after network status changes
NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
switch (internetStatus)
{
case NotReachable:
{
[self displayMessageWithTitle:@"ERROR"
andMessage:@"Unable To Connect to Internet"
andOKButton:@"OK"];
[self dismissModalViewControllerAnimated:YES];
break;
}
case ReachableViaWiFi:
{
NSLog(@"The internet is working via WIFI.");
break;
}
case ReachableViaWWAN:
{
NSLog(@"The internet is working via WWAN.");
break;
}
}
NetworkStatus hostStatus = [hostReachable currentReachabilityStatus];
switch (hostStatus)
{
case NotReachable:
{
// NSLog(@"A gateway to the host server is down.");
[self displayMessageWithTitle:@"ERROR"
andMessage:@"Host Not Reachable"
andOKButton:@"OK"];
[self dismissModalViewControllerAnimated:YES];
break;
}
case ReachableViaWiFi:
{
NSLog(@"A gateway to the host server is working via WIFI.");
break;
}
case ReachableViaWWAN:
{
NSLog(@"A gateway to the host server is working via WWAN.");
break;
}
}
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
[activityIndicator startAnimating];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[activityIndicator stopAnimating];
}
// Since this ViewController is presented Modally, this method removes it
// via a button click:
-(IBAction) dismissWebTixView:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}
-(void) viewWillDisappear:(BOOL)animated {
NSLog(@"In webForTix's 'viewWillDisappear' method....");
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kReachabilityChangedNotification
object:nil];
}
// Was told it might be good to put "removeObserver" here and not in viewWillDisappear
// well neither worked - the App still crashes....
- (void)dealloc
{
//NSLog(@"In webForTix's dealloc method....");
// [[NSNotificationCenter defaultCenter] removeObserver:self
// name:kReachabilityChangedNotification
// object:nil];
NSLog(@"In webForTix's dealloc method - removedObserver...");
[super dealloc];
}
My App was working perfectly well until I incorporated the Reachability .h and .m files to it to check for internet connectivity. While for the most part everything still runs perfectly well (all web pages load correctly, and when I purposefully turn-off my Airport to test things, Reachability catches it gracefully) - I do now get inexplicable crashes at odd times, with the dreaded "Exc-Bad-Access" error...
I ran Instruments and found the Zombie - see screen-grab:
Looking at the "RefCt" column, you can see it reaches 15 - and I've seen it go higher than 20!
In the "Responsible Caller" column (far right), I see all sorts of methods that I don't recognize - and who's call I certainly didn't initiate -- I'm assuming they're called by the system internally during run-time?
Either way, I followed Apple's Reachability code & instructions very carefully, as well as the tips from this very highly-ranked stackoverflow thread:
How to check for an active Internet connection on iOS or OSX?
But I'm still getting these inexplicable crashes.
Can anyone offer any advice?
Here's the code:
#import "Reachability.h"
-(void) viewWillAppear:(BOOL)animated
{
// check for internet connection
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil];
internetReachable = [[Reachability reachabilityForInternetConnection] retain];
[internetReachable startNotifier];
// check if a pathway to a random host exists
hostReachable = [[Reachability reachabilityWithHostName: @"www.apple.com"] retain];
[hostReachable startNotifier];
// now patiently wait for the notification
}
-(void) viewDidLoad {
url = [NSURL URLWithString: @"http://www.google.com"];
NSURLRequest *req = [NSURLRequest requestWithURL: url];
[webPageView loadRequest:req];
[super viewDidLoad];
}
-(void) checkNetworkStatus:(NSNotification *)notice
{
// called after network status changes
NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
switch (internetStatus)
{
case NotReachable:
{
[self displayMessageWithTitle:@"ERROR"
andMessage:@"Unable To Connect to Internet"
andOKButton:@"OK"];
[self dismissModalViewControllerAnimated:YES];
break;
}
case ReachableViaWiFi:
{
NSLog(@"The internet is working via WIFI.");
break;
}
case ReachableViaWWAN:
{
NSLog(@"The internet is working via WWAN.");
break;
}
}
NetworkStatus hostStatus = [hostReachable currentReachabilityStatus];
switch (hostStatus)
{
case NotReachable:
{
// NSLog(@"A gateway to the host server is down.");
[self displayMessageWithTitle:@"ERROR"
andMessage:@"Host Not Reachable"
andOKButton:@"OK"];
[self dismissModalViewControllerAnimated:YES];
break;
}
case ReachableViaWiFi:
{
NSLog(@"A gateway to the host server is working via WIFI.");
break;
}
case ReachableViaWWAN:
{
NSLog(@"A gateway to the host server is working via WWAN.");
break;
}
}
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
[activityIndicator startAnimating];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[activityIndicator stopAnimating];
}
// Since this ViewController is presented Modally, this method removes it
// via a button click:
-(IBAction) dismissWebTixView:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}
-(void) viewWillDisappear:(BOOL)animated {
NSLog(@"In webForTix's 'viewWillDisappear' method....");
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kReachabilityChangedNotification
object:nil];
}
// Was told it might be good to put "removeObserver" here and not in viewWillDisappear
// well neither worked - the App still crashes....
- (void)dealloc
{
//NSLog(@"In webForTix's dealloc method....");
// [[NSNotificationCenter defaultCenter] removeObserver:self
// name:kReachabilityChangedNotification
// object:nil];
NSLog(@"In webForTix's dealloc method - removedObserver...");
[super dealloc];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您必须仔细平衡对 addObserver 和 removeObserver 的调用。
如果您在 vieWillAppear 中为通知添加了观察者,则需要在 viewWillDisappear 中将其删除。
如果您添加观察者两次,您将因同一个通知而被调用两次,并且必须调用removeObserver两次才能删除这两个通知。
我没有看到任何明显的内存管理问题。看起来您发布的所有代码都在创建自动释放的对象,这应该没问题。
You have to carefully balance calls to addObserver and removeObserver.
If you add an observer for a notification in vieWillAppear, you need to remove it in viewWillDisappear.
If you add observer twice, you will get called twice for the same notification, and have to call removeObserver twice in order to get rid of both notifications.
I didn't see any obvious memory management problems. It looks like all the code you posted is creating auto-released objects, which should be fine.