IOS GCD 사용(다 핵 프로 그래 밍)

7878 단어 gcd
본문 주소:IOS 사용 GCD(다 핵 프로 그래 밍)
탕 교
GCD 가 뭐야?
그 랜 드 센트 럴 디 스 패 치(GCD)는 애플 이 개발 한 다 핵 프로 그래 밍 의 해법 이다.이 방법 은 맥 OS X 10.6 눈 표범 에서 처음 출시 됐 고,이후 iOS 4.0 에 도입 됐다.GCD 는 NSThread,NSOperation Queue,NSInvocation Operation 등 기술 을 대체 하 는 효율 적 이 고 강력 한 기술 로 다른 언어의 클 로 저(Closure)처럼 보이 지만 애플 은 이 를 Blocks 라 고 부른다.
예 를 들다
프로 그래 밍 장면 을 봅 시다.우 리 는 아이 폰 에 웹 페이지 를 다운로드 하 는 기능 을 하려 고 합 니 다.이 기능 은 매우 간단 합 니 다.바로 아이 폰 에 단 추 를 놓 고 이 단 추 를 누 르 면 돌아 가 는 원 을 표시 하여 다운로드 가 진행 되 고 있 음 을 표시 합 니 다.다운로드 가 완 료 된 후에 화면 에 있 는 텍스트 컨트롤 에 내용 을 불 러 옵 니 다.
GCD 안 쓰기 전에.
기능 은 간단 하지만 다운로드 과정 을 배경 스 레 드 에 넣 어야 합 니 다.그렇지 않 으 면 UI 스 레 드 가 표시 되 지 않 습 니 다.따라서 GCD 를 사용 하지 않 는 다 면 다음 과 같은 세 가지 방법 을 써 야 합 니 다.
somewick 방법 은 단 추 를 누 른 후의 코드 입 니 다.NSInvocation Operation 으로 배경 스 레 드 를 만 들 고 NSOperation Queue 에 넣 는 것 을 볼 수 있 습 니 다.백 스테이지 스 레 드 실행 download 방법..
다운로드 방법 은 웹 페이지 를 다운로드 하 는 논 리 를 처리 합 니 다.다운로드 완료 후 permselector OnMainThread 로 download 실행completed 방법.
download_completed 는 clear up 작업 을 하고 다운로드 한 내용 을 텍스트 컨트롤 에 표시 합 니 다
이 세 가지 방법의 코드 는 다음 과 같다.다운로드 시작->다운로드 중->다운로드 완료 3 단계 가 전체 기능 의 3 단계 임 을 알 수 있 습 니 다.하지만 그것들 은 세 조각 으로 잘 렸 다.그들 사이 에는 세 가지 방법 이기 때문에 데이터 파 라미 터 를 전달 해 야 한다.복잡 한 응용 이 라면 데이터 매개 변 수 는 본 사례 의 NSString 처럼 간단 하지 않 을 수 있 습 니 다.또한 다운 로드 는 Model 의 클래스 에 넣 을 수 있 고 인터페이스의 통 제 는 View Controller 층 에 넣 어서 할 수 있 습 니 다.이 는 원래 분 리 된 코드 를 더욱 분산 시 킬 수 있 습 니 다.코드 의 가 독성 이 크게 떨어지다.
static NSOperationQueue * queue;
- (IBAction)someClick:(id)sender {
    self.indicator.hidden = NO;
    [self.indicator startAnimating];
    queue = [[NSOperationQueue alloc] init];
    NSInvocationOperation * op = [[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil] autorelease];
    [queue addOperation:op];
}

- (void)download {
    NSURL * url = [NSURL URLWithString:@"http://www.youdao.com"];
    NSError * error;
    NSString * data = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
    if (data != nil) {
        [self performSelectorOnMainThread:@selector(download_completed:) withObject:data waitUntilDone:NO];
    } else {
        NSLog(@"error when download:%@", error);
        [queue release];
    }
}

- (void) download_completed:(NSString *) data {
    NSLog(@"call back");
    [self.indicator stopAnimating];
    self.indicator.hidden = YES;
    self.content.text = data;
    [queue release];
}

GCD 사용 후
GCD 를 사용 하면 위의 세 가지 방법 을 함께 사용 할 수 있 습 니 다.다음 과 같 습 니 다.
//      
self.indicator.hidden = NO;
[self.indicator startAnimating];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    //      
    NSURL * url = [NSURL URLWithString:@"http://www.youdao.com"];
    NSError * error;
    NSString * data = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
    if (data != nil) {
        //      
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.indicator stopAnimating];
            self.indicator.hidden = YES;
            self.content.text = data;
        });
    } else {
        NSLog(@"error when download:%@", error);
    }
});

우선 코드 가 짧 아 졌 다 는 것 을 볼 수 있다.원래 세 가지 방법의 정의 가 적 고 서로 전달 해 야 할 변수의 패키지 도 적 기 때문이다.
또한 코드 가 명확 해 졌 습 니 다.비동기 코드 이지 만 GCD 에 의 해 합 리 적 으로 통합 되 어 논리 가 매우 뚜렷 합 니 다.MVC 모드 를 적용 하면 View Controller 층 의 리 셋 함 수 를 모 달 층 에 GCD 방식 으로 전달 할 수도 있 습 니 다.이 는 이전@selector 방식 보다 코드 의 논리 적 관 계 를 더 잘 알 수 있 습 니 다.
GCD 의 정의
간단 한 GCD 의 정 의 는 함수 포인터 와 비슷 합 니 다.차 이 는 함수 포인터 의*번 호 를^로 대체 한 것 입 니 다.다음 과 같 습 니 다.
 //     
 (void) (^loggerBlock)(void);
 //   

 loggerBlock = ^{
      NSLog(@"Hello world");
 };
 //   
 loggerBlock();

그러나 대부분의 경우,우 리 는 보통 내 연 된 방식 으로 그것 을 정의 합 니 다.프로그램 블록 을 호출 함수 에 쓰 려 고 합 니 다.예 를 들 어 다음 과 같 습 니 다.
 dispatch_async(dispatch_get_global_queue(0, 0), ^{
      // something
 });

위 에서 보 듯 이 block 은 다음 과 같은 특징 이 있 습 니 다.
프로그램 블록 은 코드 에서 내 연 된 방식 으로 정의 할 수 있 습 니 다
프로그램 블록 은 생 성 범위 내 에서 사용 가능 한 변수 에 접근 할 수 있 습 니 다
시스템 에서 제공 하 는 dispatch 방법
애플 은 GCD 를 편리 하 게 사용 하기 위해 블록 을 메 인 스 레 드 나 백 스테이지 스 레 드 에 놓 고 실행 하거나 연기 하 는 방법 을 제공 했다.사용 한 예 는 다음 과 같다.
//      :
 dispatch_async(dispatch_get_global_queue(0, 0), ^{
      // something
 });
 //      :
 dispatch_async(dispatch_get_main_queue(), ^{
      // something
 });
 //      :
 static dispatch_once_t onceToken;
 dispatch_once(&onceToken, ^{
     // code to be executed once
 });
 //   2   :
 double delayInSeconds = 2.0;
 dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
 dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
     // code to be executed on the main queue after delay
 });

dispatch_queue_t 도 스스로 정의 할 수 있 습 니 다.queue 를 정의 하려 면 dispatch 를 사용 할 수 있 습 니 다.queue_create 방법,예 는 다음 과 같다.
dispatch_queue_t urls_queue = dispatch_queue_create("blog.devtang.com", NULL);
dispatch_async(urls_queue, ^{
     // your code
});
dispatch_release(urls_queue);

또한 GCD 는 배경 2 개의 스 레 드 를 병행 하 게 한 다음 2 개의 스 레 드 가 모두 끝 난 후에 실행 결 과 를 모 으 는 등 고급 용법 도 있다.이 건 dispatchgroup, dispatch_group_async 와 dispatchgroup_notify 가 실현 합 니 다.예 는 다음 과 같 습 니 다.
dispatch_group_t group = dispatch_group_create();
 dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
      //         
 });
 dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
      //         
 });
 dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{
      //     
 });

block 이외 의 변 수 를 수정 합 니 다.
기본 적 인 상황 에서 프로그램 블록 에 접근 하 는 외부 변 수 는 과 거 를 복사 합 니 다.즉,쓰기 동작 이 원 변수 에 적용 되 지 않 습 니 다.하지만 당신 은 를 더 할 수 있 습 니 다.block 은 쓰기 동작 을 유효 하 게 합 니 다.예제 코드 는 다음 과 같 습 니 다.
 __block int a = 0;
 void  (^foo)(void) = ^{
      a = 1;
 }
 foo();
 //   ,a      1

백그라운드 실행
GCD 의 또 다른 용 도 는 프로그램 이 배경 에서 오래 실 행 될 수 있 도록 하 는 것 이다.GCD 를 사용 하지 않 았 을 때 앱 이 홈 키 를 눌 러 종료 되면 앱 이 최대 5 초 동안 자원 을 저장 하거나 정리 하 는 작업 을 합 니 다.하지만 GCD 를 사용 한 후 앱 은 최대 10 분 동안 백 스테이지 에서 오래 실 행 됩 니 다.이 시간 은 로 컬 캐 시 를 정리 하고 통계 데 이 터 를 보 내 는 등 작업 을 할 수 있다.
프로그램 을 배경 에서 오래 실행 시 키 는 예제 코드 는 다음 과 같 습 니 다.
// AppDelegate.h  
@property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundUpdateTask;

// AppDelegate.m  
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [self beingBackgroundUpdateTask];
    //                
    [self endBackgroundUpdateTask];
}

- (void)beingBackgroundUpdateTask
{
    self.backgroundUpdateTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        [self endBackgroundUpdateTask];
    }];
}

- (void)endBackgroundUpdateTask
{
    [[UIApplication sharedApplication] endBackgroundTask: self.backgroundUpdateTask];
    self.backgroundUpdateTask = UIBackgroundTaskInvalid;
}

총결산
전체적으로 말 하면 GCD 는 개발 자가 다 중 스 레 드 프로 그래 밍 을 하 는 데 큰 편 의 를 줄 수 있다.만약 당신 의 app 이 iOS 4.0 이하 의 시스템 을 지원 할 필요 가 없다 면,가능 한 한 GCD 를 사용 하여 배경 스 레 드 와 UI 스 레 드 의 상호작용 을 처리 해 야 합 니 다.
Posted by 당 교 Feb 22nd, 2012  iOS

좋은 웹페이지 즐겨찾기