[iOS] objective-c 비동기 처리 (dispatch_async)
아이폰 앱에서 로그인시 VPN 연동을 개발하고 있었는데, VPN 접속 시간이 몇 초 걸리는 관계로 연결 성공 여부를 곧바로 체크할 수 없는 상황이었다. 쓰레드 또는 비동기 처리가 필요했는데, 쓰레드는 다소 어려워보였고 GCD(Grand Central Dispatch) 라는 개념의 코드가 있어서 가져다 잘 썼다.
코드는 아래와 같으며, 코드 출처는 http://seorenn.blogspot.com/2012/04/ios.html 이다.
|
// 여기서부터 비동기 코드 시작. // dispatch_async 함수는 내부블럭의 코드 실행에 영향을 받지 않고 바로 실행이 끝난다. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{ // 작업이 오래 걸리는 API를 백그라운드 스레드에서 실행한다. BOOL res = [self heavyOperatingMethod]; dispatch_async(dispatch_get_main_queue(), ^{ // 이 블럭은 메인스레드(UI)에서 실행된다. if (res) { [self operationSucceed]; } else { [self operationFailed]; } }); }); |
위 예제 코드를 십분 활용하여 실제로는 아래와 같이 짰다.
|
-(BOOL)loginVPN { // (중략. VPN 연결 시도하는 코드) // VPN 연결 체크 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{ // VPN 연결 성공했는지 비동기로 체크 BOOL res = [self checkVPNConnection];
dispatch_async(dispatch_get_main_queue(), ^{ // 비동기 메서드 결과가 리턴되면 아래 로직 수행 if (res) { [self loginAfterVPN]; } else { [LoginUtil alert:@”VPN 연결이 원활하지 않습니다. 잠시후 다시 시도해주세요.”]; } }); });
// NO를 리턴하면 다음 로직을 타지 않게 됨. 다음 로직은 비동기 메서드의 결과가 리턴되면 loginAfterVPN 에서 계속됨. return NO; } // VPN 연결 성공했는지 비동기로 체크. // 반복문을 돌면서 2초마다 한 번씩 VPN 연결 성공했는지 체크. -(BOOL)checkVPNConnection {
for (int i=0; i<10; i++) { NSLog(@”CHECK VPN…”);
BOOL t2 = [self vpnStatusCheck]; if (t2) { return YES; }
// 2초 sleep [NSThread sleepForTimeInterval:2.000]; }
return NO; } |