2011-08-01 4 views
0

대기열에 제출하는 블록이 있으며 특정 조건이 참일 경우에만 블록을 실행하고 싶습니다. 그것은 다음과 같은 종류의 외모 :코드 블록에서 변수를 참조로 사용하는 방법은 무엇입니까?

bool hi = YES; 
dispatch_async(queue, ^{ 
    if (hi == YES) 
     do stuff; 
}); 

이 가진 문제입니다 블록 후 블록의 NO 외부 인사 변화의 값은 큐에 있지만 실행되기 전에 제출 된 경우 블록 안의 hi 값은 여전히 ​​YES입니다.

설명서를 살펴본 결과 __block 지시어가 발견되었지만 도움이 될 수 있지만 작동하지는 않았습니다.

__block bool hi = YES; 
dispatch_async(queue, ^{ 
    if (hi == YES) 
     do stuff; 
}); 

bool hi = YES; 
dispatch_async(queue, ^{ 
    __block boolean hi2 = hi; 
    if (hi2 == YES) 
     do stuff; 
}); 

을 그리고 그 중 어느 것도 작동하는 것 : 나는 시도했습니다.

답변

2

__block BOOL hi 어떻게해야 * 실행시 역 참조 아직도 주위에있을 필요가 네가 원해. 비동기 적으로 디스 패칭 할 경우 나머지 블록이 없어도 hi를 NO로 변경하기 전에 if (hi == YES)이 실행될 가능성이 있습니다. 실제로해야 할 일은 주기적으로 hi를 확인하여 시작해야하는지 한 번 확인하기보다는 계속 작업해야하는지 확인하는 것입니다.

+0

Martin을 실행하면 예상대로 작동하므로 __block 지시문에 참조가 저장됩니다. BOOL b = YES; \t 공극 (^ 블록)() = [^ { \t \t 경우 (b == YES) { \t \t \t NSLog (@ "B == YES"); \t \t} else { \t \t \t NSLog (@ "b == NO"); \t \t} \t} [autorelease]; \tb = NO; \t block(); – Mattia

1

블록의 전문가가 아니기 때문에 원시 변수의 값을 캡처하지 않는 방법이 있는지 모르겠다. (하지만 생각하지 않는다). 염두에 두는 해결책은 문제를 해결하기 위해 포인터 또는 NSNumber를 사용하는 것입니다.

포인터

/* this obviously needs to still be around to be dereferenced when the block executes */ 
BOOL hi = YES; 
BOOL* hiPtr = &hi; 

dispatch_async(queue, ^{ 
    if (*hiPtr == YES) 
     do stuff; 
}); 

의 NSNumber

/*이 분명 블록/

__block NSNumber* hi = [NSNumber numberWithBool: YES]; 

dispatch_async(queue, ^{ 
    if ([hi boolValue] == YES) 
     do stuff; 
}); 
관련 문제