2014-05-17 3 views
0

이 항목은 iOS 앱에 있습니다. 나는 GCD를 배우고있다. 그래서, 간단한 것을 시험해보십시오.GCD 비동기 메서드의 동작을 이해할 수 없습니다.

여기의 결과는 나를 혼란스럽게합니다. 왜 항상 2. 진술 문이 먼저오고 그 다음에 1.가 오나요? 두 작업을 GCD로 보내지 만 우선 먼저 설정합니다. 정말 큰 일이 아니기 때문에 set과 2.set은 시간이 겹칠 것입니다. 실행중인 스레드를 인쇄하는 간단한 작업.

나는 스레딩 환경에서 발생하는 것과 다른 결과를 줄 것이라고 예상하면서 여러 번 실행했습니다.

설명해주십시오. 여기

2. Crnt Thread = <NSThread: 0x10920fee0>{name = (null), num = 1} 
2. Main thread = <NSThread: 0x10920fee0>{name = (null), num = 1} 
1. Crnt Thread = <NSThread: 0x10920fee0>{name = (null), num = 1} 
1. Main thread = <NSThread: 0x10920fee0>{name = (null), num = 1} 
3. Crnt Thread = <NSThread: 0x10920fee0>{name = (null), num = 1} 
3. Main thread = <NSThread: 0x10920fee0>{name = (null), num = 1} 

코드 :

void displayAlertView(void *paramContext) 
{ 

    NSLog(@"3. Crnt Thread = %@",[NSThread currentThread]); 
    NSLog(@"3. Main thread = %@", [NSThread mainThread]); 
} 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    // Override point for customization after application launch. 
    dispatch_queue_t myQueue = dispatch_get_main_queue(); 
    AlertViewData *contextData = (AlertViewData *)malloc(sizeof(AlertViewData)); 
    dispatch_async(myQueue,^(void){ 
     NSLog(@"1. Crnt Thread = %@",[NSThread currentThread]); 
     NSLog(@"1. Main thread = %@", [NSThread mainThread]); 
    }); 
    if(contextData != NULL) 
    { 
     NSLog(@"2. Crnt Thread = %@",[NSThread currentThread]); 
     NSLog(@"2. Main thread = %@", [NSThread mainThread]); 

     dispatch_async_f(myQueue, contextData, displayAlertView); 
    } 

    return YES; 
} 

답변

0

다음은 비동기 블록을 설치하고 실행할 수있는 기회가 전에 그 코드가 실행하기 때문에 "2"문이 먼저 온다. 그 점은 dispatch_async입니다. 이러한 코드는 다른 스레드에서 실행되며 현재 스레드는 기쁜 방법으로 계속 실행됩니다.

두 로그 블록 모두를 업데이트하여 100 개의 로그 문을 기록하는 루프를 사용하면 "1"과 "2"문이 혼합되어 표시 될 수 있습니다.

두 로그만으로는 "2"로그가 완료되기 전에 "2"로그가 완료되기 전에 "2"로그가 완료됩니다. 로그에있는 타임 스탬프를 보면 로그의 타임 스탬프를 볼 수 있습니다.

위가 myQueue 백그라운드 큐 있다는 가정하에 쓰여졌다

UPDATE. 마틴이 지적했듯이, 그것은 메인 큐입니다. 그것이 메인 큐이므로, 대답은 꽤 다릅니다.

메인 대기열에서 비동기 호출을 수행하기 때문에 모든 것이 동일한 주 스레드에서 수행됩니다. dispatch_async을 호출 할 때마다 전화를 줄 끝에 추가하는 것과 같습니다.

현재 실행중인 코드는 행의 맨 위에 있습니다. "1"로그가있는 블록에 대해 dispatch_async을 호출하면 해당 블록이 해당 라인의 끝에 추가되고 현재 코드가 완료 될 때 실행됩니다. 그런 다음 "3"로그에 대해 dispatch_async_f을 호출합니다. 그것들은 줄 끝까지 추가됩니다 ("1"로그 이후).

그래서 현재 runloop이 완료되고 didFinishLaunchingWithOptions` 메서드가 반환되면 다음 줄의 다음 비트가 실행됩니다. 이것은 "1"로그입니다. 이 작업이 완료되면 대기열의 다음 블록이 실행됩니다 ("3"로그).

+1

완전히 정확하지 않다고 생각합니다. 블록은 주 스레드에서만 실행되는 * 주 * 큐에 전달됩니다. didFinishLaunchingWithOptions가 직렬 대기열이기 때문에 반환 될 때 실행됩니다. –

+0

@rmaddy : 자세히 설명해 주시겠습니까? GCD 블록은 일반적인 기능을 호출하는 것보다 프로세서 코어에서 더 많은 오버 헤드를 제공합니까? 그런 이유로 2 세트의 계산서가 처음으로 달릴 예정입니까? – Chandu

+0

@MartinR 죄송합니다 - 'myQueue'가 메인 큐입니다. 그에 따라 내 대답을 업데이트 할 것입니다. – rmaddy

관련 문제