我的iPhone应用程序正在开发中遇到一个非常奇怪的崩溃。似乎每当我向朋友展示我的应用程序时它都会崩溃,但是否则它永远不会崩溃。在被墨菲的法律方面普遍迷惑之后,我已经确定了崩溃的模式 - 纽约市地铁。我使用地铁后,我的应用程序一直崩溃。我已将问题追溯到我对Reachability
的使用。应用程序在无网络情况(不包括飞行模式)下使用后,下次崩溃。在执行任何其他网络操作之前,我遵循Apple的指导原则并检查与Reachability
的连接,但我发现了一些有关如何调用它的相互矛盾的文档。
目前我正在做这样的事情:
-(BOOL)reachable {
Reachability *r = [Reachability reachabilityWithHostName:@"www.stackoverflow.com"];
NetworkStatus internetStatus = [r currentReachabilityStatus];
if(internetStatus == NotReachable) {
return NO;
}
return YES;
}
我正在调用与viewDidAppear调用的方法同步。
if ([self reachable]== YES) {
... do network stuff ...
基于Reachability Guide for iOS 4
的代码我的问题:是否正确使用Reachability
来处理此错误并处理缺少3G或Wifi网络的问题?我是否需要生成另一个线程或执行某些操作来删除同步调用?
顺便说一句,这是我在应用程序崩溃时看到的崩溃日志,这让我认为这是一个同步/异步问题。
Application Specific Information: (app name) failed to resume in time Elapsed total CPU time (seconds): 3.280 (user 1.770, system 1.510), 33% CPU Elapsed application CPU time (seconds): 0.040, 0% CPU Thread 0 name: Dispatch queue: com.apple.main-thread Thread 0: 0 libsystem_kernel.dylib 0x30747fbc kevent + 24 1 libsystem_info.dylib 0x30abec4e _mdns_search + 586 2 libsystem_info.dylib 0x30abfb72 mdns_addrinfo + 370 3 libsystem_info.dylib 0x30abfd68 search_addrinfo + 76 4 libsystem_info.dylib 0x30ac1bcc si_addrinfo + 1080 5 libsystem_info.dylib 0x30abd0b2 getaddrinfo + 78 6 SystemConfiguration 0x311b4256 __SCNetworkReachabilityGetFlags + 962 7 SystemConfiguration 0x311b4f1e SCNetworkReachabilityGetFlags + 98
答案 0 :(得分:4)
在同步的情况下,你可能会被iOS应用程序看门狗杀死。这是因为要进行可达性检查,SCNetworkReachability功能需要进行DNS查找,这可能需要长达30秒。如果在主线程上检查可达性(即在viewDidAppear中),您可能会长时间阻塞主线程,iOS认为您的应用程序已挂起,应用程序监视器会在20秒后将其杀死。
Apple甚至在Reacahbility示例代码中警告这一点:
Apple Reachability Sample Code README
只需使用Reachability示例应用程序中的通知 - 它可以很好地工作,并且在您了解NSNotificationCenter设计模式后非常简单。
祝你好运!答案 1 :(得分:-1)
我通过将其设置为异步解决了我的问题。我称这样的方法
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSTimer *timer = [NSTimer timerWithTimeInterval:0 target:self selector:@selector(loadData) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
[pool release];
并且调用的方法看起来像这样
- (void)loadData {
// check for reachability first before starting data load
if ([self reachable]== NO) {
// display error message that there is no internet connection, e.g.
UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:@"Connection Error" message:@"Cannot load data. There is no internet connection." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Retry",nil];
[errorAlert show];
[errorAlert release];
} else {
// do something to load data from internet ...
}
}
使用与上述相同的可访问代码。
我想说总是像这样使用Reachability - Apple给出的例子是不完整的。我已经在已完成的应用程序上运行了几个月的代码并且它非常稳定。
修改强> 从iOS 5开始,此代码不再稳定 - 由于“超出允许时间的主动断言”,它现在有时会崩溃。自从我写这个问题以来,Apple已经更新了他们的文档和示例代码,因此我建议在另一个答案中关注该链接。