2011-05-05 4 views
7

개발중인 iPhone 앱과 매우 이상한 충돌이 발생했습니다. 친구에게 내 앱을 보여줄 때마다 충돌 할 것 같았지만 그렇지 않은 경우에는 절대로 충돌하지 않는 것 같았습니다. Murphy 's Law 측면에서 일반적으로 신비화 된 후, 나는 뉴욕시 지하철의 충돌 패턴을 결정했습니다. 지하철을 사용하면 내 앱이 계속 충돌합니다. 나는 Reachability을 사용하여이 문제를 추적했다. 앱이 네트워크가없는 상황 (비행기 모드 제외)에서 사용 된 후 다음에 앱이 다운됩니다. 다른 네트워크 작업을 수행하기 전에 Apple의 지침을 따르고 Reachability과의 연결을 확인하고 있지만이를 호출하는 방법에 대한 몇 가지 충돌하는 설명서를 발견했습니다. 네트워크가없는 상황에서 도달 가능성으로 인해 충돌이 발생합니다. 도달 가능성을 비동기 적으로 올바르게 사용하는 방법

현재 나는이 같은 일을 해요 :

-(BOOL)reachable { 
    Reachability *r = [Reachability reachabilityWithHostName:@"www.stackoverflow.com"]; 
    NetworkStatus internetStatus = [r currentReachabilityStatus]; 
    if(internetStatus == NotReachable) { 
     return NO; 
    } 
    return YES; 

} 내가 viewDidAppear에서 호출하는 방법과 동 기적으로 호출하고있어

. Reachability Guide for iOS 4

내 질문에서 코드를 기반으로

if ([self reachable]== YES) { 
     ... do network stuff ... 

:이 오류를 돌봐 및 3G 또는 와이파이 네트워크의 부재를 처리 할 Reachability의 적절한 사용은 무엇입니까? 동기 호출을 제거하기 위해 다른 스레드를 생성하거나 무언가를해야합니까?

여기 내 앱이 충돌 할 때 볼 수있는 충돌 로그가 있습니다. 이로 인해 동기/비동기 문제라고 생각하게됩니다.

 

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 

답변

-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 ...  
    } 

} 

과 같은 형태 호출합니다.

필자는 항상 도달 가능성을 사용한다고 말하고 싶습니다. Apple이 제공하는 예는 불완전합니다. 몇 달 동안 완성 된 앱에서이 코드를 실행했지만 매우 안정적이었습니다.

편집 : 이 코드는 더 이상 안정에서 iOS 5의있는 그대로 - 지금 때때로 "허용 시간을 넘어 활성 주장"에 의한 충돌 할 수 없다. Apple은이 질문을 쓴 이후로 자신의 문서와 예제 코드를 업데이트 했으므로 다른 답변에서 그 링크를 따라가는 것이 좋습니다.

4

동기식 경우에는 iOS Application Watchdog에 의해 사망하고있는 것입니다. 도달 가능성 검사를 수행하기 때문에 SCNetworkReachability 기능은 최대 30 초가 걸릴 수있는 DNS 조회를 수행해야합니다. 주 스레드 (예 : viewDidAppear)에서 도달 가능성을 확인하면 잠재적으로 오랜 시간 동안 주 스레드를 차단하므로 iOS는 앱이 중단되고 20 초 후에 응용 프로그램 워치 독이이를 종료한다고 생각합니다.당신은 NSNotificationCenter 디자인 패턴을 grok 수하면 잘 작동하고 매우 간단 ---

Apple Reachability Sample Code README

는 그냥 도달 가능성 샘플 응용 프로그램에서 같은 알림을 사용

애플은 심지어 Reacahbility 샘플 코드에서 이것에 대해 경고 .

행운을 빈다.

+0

감사합니다. 주 스레드가 죽은 경우 동기식으로 확인할 때 보았던 것과 일치합니까? (응용 프로그램이 도달하기 위해 동기 확인 후 실행되는 NEXT 시간이 충돌합니다) –

관련 문제