2012-03-30 1 views
4

1 초마다 백그라운드에서 메소드를 수행하려는 iPhone 애플리케이션이 있습니다.iPhone SDK - 백그라운드 스레드에서 반복 프로세스 실행

그래서 내 메인 스레드에서, 나는 나의 UIViewControllerviewDidLoad()에 다음 코드를 다음 방법으로

[NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(repeatedMethod) userInfo:nil repeats:YES]; 

:

-(void)repeatedMethod { 
    if(!processIsRunning) { 
    processIsRunning = YES; 
    [self performSelectorInBackground:@selector(runProcessInBackground:) withObject:myImage]; 
    } 
} 

-(void)runProcessInBackground:(UIImage *)image { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    ... Some operations ... 
    ... also call a method on the main thread which sets isProcessRunning to NO 

    [pool release] 
} 

나는이 설정 한 방법, 새 스레드 매 초마다 생성됩니다 (프로세스가 아직 실행 중이 아니면 내 processIsRunning 플래그 덕분).

자, 내 질문은 :

(1)이이 작업을 수행하는 가장 좋은 방법이 있나요? 아니면 배경 스레드를 유지하고 재사용하는 더 적절한 방법이 있습니까?

(2) 가장 빠른 방법은 무엇입니까? 메소드가 호출 될 때마다 새로운 백그라운드 스레드를 회전 시켜서 시간을 잃어 버리는가?

코드는 정상적으로 작동합니다. 주 스레드에서 모든 것을 실행했을 때 코드가 약간 느려졌습니다 (궁극적으로는 수행하고 싶지 않음).

모든 조언은 훌륭합니다! 전에이 유형의 질문을 다루는 사람이 있습니까?

많은 감사, 브렛 귀하의 코멘트에서 질문을 바탕으로

+0

이 질문에 대한 내 대답을보십시오. http://stackoverflow.com/questions/8759264/worker-thread-ios/8759329#8759329 –

+0

@Andrew, Thanks! 한 가지 질문 : GCD와 관련하여 어떻게 객체를 전달할 수 있습니까? 위의 코드에서이 객체는 'myImage'입니다. – Brett

답변

13

, 나는 내가 진짜 대답에 내 의견을 확장 거라고 생각. 이것을 위해 GCD를 사용할 수 있으며, 아마도 가장 좋은 방법 일 것입니다. 이 같은

뭔가 : 블록에 대한 멋진 것들을

dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
dispatch_source_t timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, backgroundQueue); 
dispatch_source_set_timer(timerSource, dispatch_time(DISPATCH_TIME_NOW, 0), 1.0*NSEC_PER_SEC, 0*NSEC_PER_SEC); 
dispatch_source_set_event_handler(timerSource, ^{ 
    [self repeatedMethod]; 
}); 
dispatch_resume(timerSource); 

- (void)repeatedMethod { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    [self doStuffWithAnImage:self.myImage]; 

    [pool drain]; 
} 

하나는 지역의 범위를 캡처 할 수 있습니다. 위의 예에서 실제로 사용하지는 않았지만 GCD에 사물을 "전달"합니다. 이 질문에 대한 내 대답을보십시오 : Is there an advantage to using blocks over functions in Objective-C?.

+0

이것은 실제로 유익한 정보입니다! 고맙습니다. 그러나 그것은 하나의 (잘하면) 마지막 질문으로 연결됩니다. 다른 질문에 대한 귀하의 답변에서 블록이 생성 당시 로컬 범위를 유지한다는 것을 나타냅니다 (즉, 다른 대답에서 num1 = 42). 필자의 경우, self.image를 주 스레드에서 수시로 업데이트하고 싶습니다. [self doStuffWithAnImage : self.myImage]가 (메인 스레드가 설정 한대로) 가장 최근의 이미지에 접근 할 수 있습니까? 아니면 GCD 스레드 생성시 존재했던 self.image를 유지합니까? 다시 한 번 감사드립니다! – Brett

+0

'self.myImage'는'[self myImage]'와 같습니다. 실제로'-myImage' 접근 자 메소드를 호출하기 때문에 블록이 실행될 때 현재 값을 가져와 사용합니다. 어쨌든, 그 호출은 블록에 의해 호출되는 repeatedMethod에서 이루어진다. 블록 본문에 직접 사용 된 변수를 캡처하지만 블록 안에있는 변수를 재귀 적으로 가져 오거나 범위를 캡처하지는 않습니다 (메서드 내부의 변수가 메서드에 포함될 때까지 존재하지 않으므로 의미가 없습니다. 어쨌든 불린다). 즉, 가장 최근의 myImage를 얻을 수 있습니다. –

+0

나는 하나의 스레드에서 myImage를 설정하고 다른 스레드에서 읽기 (그리고 아마도 설정하는 것)한다는 사실은 스레드 안전에주의해야한다는 것을 추가해야한다. 백그라운드에서 읽기만하고 설정하지 않는다면 @property를 어노테이션으로 만들어서 OK 일 것입니다. 백그라운드에서 설정해야하는 경우 가장 쉬운 방법은 set 호출을 주 스레드로 다시 보내는 것입니다. –