2013-05-28 6 views
1

dispatch_async를 사용하여 때때로 웹 서버에서 변경되는 리소스를 가져옵니다 (약 60 초마다).블록을 사용하지 않고 dispatch_async

dispatch_async를 사용하고 싶지만 대신 함수 이름을 지정하고 싶습니다. 이후 나는 그 기능을 다시 자고 다시 같은 일을하고 싶어요.

내가 (이 컴파일되지 않습니다)

내가 while 루프 그래서 난이

+2

당신이'dispatch_async_f()를 사용할 수' – CodaFi

답변

0

방법에 대한 최선의 방법 무엇인지 궁금하네요 좋은 생각이 아니라고 생각 dispatch_async(self.downloadQueue, @selector(getDataThread:));을하려고하고있는 무슨이다

NSTimer *timer = [NSTimer timerWithTimeInterval:60 target:self selector:@selector(getDataThread:) userInfo:nil repeats:YES]; 
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; 

- (void)getDataThread:(id)foo { 
    dispatch_async(self.downloadQueue, ^{ 
     // code you want to run asynchronously 
    }); 
} 

... 같은 것에 대해 당신이 코드의 일부 블록은 비동기 적으로 실행하려는 것 같다 ...하지만 당신은 또한 시간 제한 간격으로 실행하려면, 그래서이 충분한다고 생각합니다. 마음 NSOperationQueue에두고

당신은 모두 당신이 NSOperationQueue 볼 수 있었다 블록과 dispatch_async 도랑하려면

는 GCD에 내장되어 있지만 직접와 인터페이스에 대해 걱정할 필요가 없습니다.

+0

멋진, 난 그 일을한다고 생각합니다. 앱이 열려있는 한이 작업을 수행하고 싶습니다. 그걸 내가 마지막에 넣을 수 있을까? – jamesatha

+0

물론 나는 그것을 잘해야한다고 생각합니다. 메소드에서 랩핑하고'applicationWillEnterForeground :'에 넣은 다음'applicationDidEnterBackground :'에서 타이머를 멈추십시오. –

+0

및 타이머를 어떻게 중지합니까? – jamesatha

4

이 관찰의 커플 : 당신이 파견 동작 타이머를 만들려면

  1. , 입력 DISPATCH_SOURCE_TYPE_TIMERdispatch_source_t 만들 예를 들어, 두 개의 클래스 속성 정의

    @property (nonatomic, strong) dispatch_queue_t queue; 
    @property (nonatomic, strong) dispatch_source_t timer; 
    

    을 그리고 타이머를 만드십시오 :

    - (void)createTimer 
    { 
        self.queue = dispatch_queue_create("com.stackoverflow.16782529", 0); 
        self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.queue); 
        if (self.timer) 
        { 
         dispatch_source_set_timer(self.timer, 
                dispatch_walltime(NULL, 0), 
                60ull * NSEC_PER_SEC, 
                1ull * NSEC_PER_SEC); 
    
         dispatch_source_set_event_handler(self.timer, ^{ 
          NSLog(@"doing something"); 
         }); 
    
         dispatch_resume(self.timer); 
        } 
    } 
    

    그런데 모두 타이머 반복, 그것은 당신의 viewDidAppear에 작성하고 viewDidDisappear에 제거하는 아마 좋은 연습 : 당신이 블록을 사용하지 않는 경우, GCD 함수의의 _f 상당하는

    - (void)viewDidAppear:(BOOL)animated 
    { 
        [self createTimer]; 
    } 
    
    - (void)viewDidDisappear:(BOOL)animated 
    { 
        dispatch_source_cancel(self.timer); 
    } 
    
  2. . 블록을 취하는 모든 GCD 함수는 대신에 C 함수를 취하는 rendition (접미사는 _f)을가집니다. 오히려 (C 함수보다는 목표 - C 방법을 사용)를 NSTimer를 사용하려는 경우, 당신은 수도

    - (void)createTimer 
    { 
        self.queue = dispatch_queue_create("com.stackoverflow.16782529", 0); 
        self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.queue); 
        if (self.timer) 
        { 
         dispatch_source_set_timer(self.timer, 
                dispatch_walltime(NULL, 0), 
                60ull * NSEC_PER_SEC, 
                1ull * NSEC_PER_SEC); 
    
         dispatch_source_set_event_handler_f(self.timer, &myTimerHandler); 
    
         dispatch_resume(self.timer); 
        } 
    } 
    
    void myTimerHandler(void *context) 
    { 
        NSLog(@"doing something"); 
    } 
    
  3. : 예를 들어, 위의 예를 사용하여, 비 블록 연주는 같을 것이다 같은 속성이 있습니다

    @property (nonatomic, strong) dispatch_queue_t queue; 
    @property (nonatomic, strong) NSTimer *timer; 
    

    을 그리고 뷰가 표시되면 다음 타이머를 생성하고이 사라질 때 제거 :

    - (void)viewDidAppear:(BOOL)animated 
    { 
        self.queue = dispatch_queue_create("com.stackoverflow.16782529", 0); 
        self.timer = [NSTimer scheduledTimerWithTimeInterval:60.0 target:self selector:@selector(handleTimer:) userInfo:nil repeats:YES]; 
    } 
    
    - (void)viewDidDisappear:(BOOL)animated 
    { 
        [self.timer invalidate]; 
    } 
    
    - (void)handleTimer:(NSTimer *)timer 
    { 
        dispatch_async(self.queue, ^{ 
         NSLog(@"doing something"); 
        }); 
    } 
    
  4. 을 개인적으로, 이 작업을 자주 확인하는 경우 끌어 오기 아키텍처 (60 초마다 데이터를 계속 가져 오는 경우)가 적합하지 않을 수 있습니다. 서버에 대한 소켓을 열고 데이터 업데이트 (이 Ray Wenderlich example 참조)가있을 때 서버에 알리거나 푸시 알림 (로컬 알림 및 푸시 알림에 대한 notifications documents 대화를 사용하지만이 애플리케이션의 경우 사용자 푸시 알림을 보게됩니다.)분명히이 두 가지 모두 서버 개발이 더 필요하지만 구조적으로 더 우아하고 효율적입니다. 당신은 당신이 비동기 네트워크 활동을 시작하는 경우, 네트워크 이벤트를 60 초마다 트리거하려는 경우 그런데

  5. 은, (중 하나는 # 3의 NSTimer 방법을 통해, 네트워크 요청이 자체가 실행되는 경우, 또는 비동기 적으로) 다른 요청을 시작하기 전에 이전 요청이 완료되었는지 확인하기 위해 일부 확인을 도입 할 수도 있습니다. 그럼에도 불구하고 그렇게할만한 일은 없을 것입니다.하지만 그럼에도 불구하고이를 점검해야합니다. dispatch_source_create 방법을 사용하고 동기 네트워크 요청을 사용하는 경우 이는 이전 문제가 완료 될 때까지 타이머가 다시 트리거되지 않기 때문에 문제가되지 않습니다. 그렇지 않으면주의하지 않으면 좋을 것입니다. 네트워크 요청으로 대기열 백업 당신은 C 함수로 리팩토링 할 수있는 경우

+0

'dispatch_source_t'는 Xcode 7.1.1에서'strong' 또는'retain' 일 수 없습니다. 코드가 컴파일되지 않습니다. –

+0

@ Cœur - 아니, 그건 사실이 아니야. 여러분이 그 오류를 보았다면 아마도 컴파일러 플래그'-DOS_OBJECT_USE_OBJC = 0'을 설정했기 때문일 것입니다. 이것은''에서 설명한 것처럼 GCD 유형에 대한 객체 동작을 끕니다. 그러나 Xcode 7.1.1 (Xcode 7.2 베타 3)에서이 문제를 다시 테스트했으며'강함'은 잘 작동합니다 (사실, 필요합니다). – Rob

+0

내 프로젝트에서 OS_OBJECT_USE_OBJC 플래그를 가지고 있지 않습니다. –