2014-05-23 1 views
1

GCD를 사용하여 다른 스레드의 인덱스로 이미지를로드하는 기능이 있습니다.컴파일러는 함수의 인수를 저장합니까?

그래서이 가정 할 수 있습니다 :

-(void)loadMainImageToIndex:(long)index 
{ 
    NSDictionary *dic=[mainData objectAtIndex:index]; 
    NSString *userImageUrl=[dic objectForKey:@"url"]; 
    NSURL *userUrl=[NSURL URLWithString:userImageUrl]; 
    [self downloadImageWithURL:userUrl completionBlock:^(BOOL succeeded, NSData *tdata) 
    { 
     if (succeeded) 
     { 

      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^
          { 

          //do something here 

          dispatch_async(dispatch_get_main_queue(),^
               { 
          //do something here that uses the index argument 

을 그리고 난이 기능을 3 번 전화 : 첫 번째 호출 스레드 작업을 종료 할 때

[self loadMainImageToIndex:0]; 
[self loadMainImageToIndex:1]; 
[self loadMainImageToIndex:2]; 

질문입니다, 그리고 지점에 도착합니다 :

dispatch_async(dispatch_get_main_queue() 

그는 index=0에서 볼 것인가, 아니면 마지막 색인 wa를 볼 것인가? s called (==2)?

질문은 그가 전체 기능을 복사하므로 끝날 때 방법을 시작한 인수를 기억할 수 있습니까? 또 다른 것은 3 번 동시에 호출하는 것은 나쁜 습관입니까?

감사합니다.

+0

실제 전체 코드를 한 번에 제공 할 수 있습니까? 가정을 돕는 것은 다소 어렵습니다. – Rickye

+0

쉽게 NSLog 인덱스를 테스트했습니다. – John

+0

예 NSLog는 올바른 답을주었습니다. 그러나 GCD 전체가 나에게 작은 "블랙 박스"이기 때문에 거기에서 무슨 일이 일어나고 있는지 이해하고 싶었습니다. 그리고 지금 나는 :) – Curnelious

답변

5

짧은 버전 : 여기에는 문제가 없습니다. 당신은 잘하고 있고 기대했던 것처럼 행동 할 것입니다 (각 블록은 올바른 값을가집니다).

긴 버전 :

-(void)loadMainImageToIndex:(long)index 

스택에 index의 새로운 사본을 누르면이 메서드에 대한 모든 호출. 메서드가 반환 될 때 파생됩니다. 이 메소드가 여러 번 병렬로 호출 되더라도 (다른 스레드에서), 각각 자체 스택에 index의 자체 사본이 있습니다. 지역 변수와 인수는 메서드 또는 함수의 각 호출에 전용입니다.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^

여기에서 블록을 만드는 것은 블록에서 발견 된 모든 변수를 "캡처"(복사)합니다. 즉 포함 index가에서 사용 있기 때문에 :

dispatch_async(dispatch_get_main_queue(),^

그래서, 여기에 아무 문제가 없습니다. 메인 대기열로 보내지는 블록은 자신이 만든 블록 index 사본을 갖게됩니다. 둘러싸는 블럭은 또한 그것이 생성 될 때 index의 사본을 만들었고, 메소드는 그것에 전달 된 값의 복사본을 index으로 만들었습니다.

"블록을 만들 때"는 dispatch_ 함수가 호출되는 지점이 아니라 ^{}이 평가되는 지점입니다. 이러한 함수는 블록을 허용하지만 블록을 작성하지는 않습니다. 블록을 생성하여 변수에 저장 한 다음 나중에 해당 블록을 다른 것으로 전달하는 것은 완전히 합법적이며 일반적입니다. 블록은 변수가 생성 된 지점에서 변수를 캡처 (복사)합니다. 이 개념을 closure이라고합니다.

+0

좋은 분명하고 완전한 대답 (투표) –

+0

대단히 감사합니다 아주 많이! – Curnelious

+0

@Rob 네이피어, 무거운 일을하는 데 몇 번이나 전화하는 것은 나쁜 습관입니까?왜냐하면 나는 때때로 이것에 대한 메모리 경고를 받기 때문이다 .. – Curnelious