적절한 해결책을 찾기 위해 많은 조사를했지만 제대로 작동하지 않았습니다. 내 iPhone 앱이 사용자 요구에 따라 NSURL 요청을 통해 데이터를 업데이트합니다. 온라인으로로드 된 각 파일은 크기가 1.5k에 불과하지만 하나의 업데이트는 이러한 파일 중 400 개로 구성 될 수 있습니다. 그래서 나는 취소 가능한 별도의 스레드에서 다운로드 작업을 수행하고 업데이트 중에 프로세스 표시 및 취소 버튼이있는 UIAlertView가 있습니다. 그 일은 1 ... 3 분이 걸릴 수 있습니다. 따라서 장치가 살아 있거나 다른 일이 발생하는 시간 초과를 초과 할 수 있으며 앱이 백그라운드로 이동합니다.iOS의 applicationDidEnterBackground에서 작업자 스레드를 취소하는 방법
applicationDidEnterBackground이 호출 될 때 아무 것도하지 않으면 내 앱이 일시 중단되었으며 작업자 스레드도 인식됩니다. 앱이 다시 포 그라운드에있을 때 깨어나서 계속 작동합니다. 여태까지는 그런대로 잘됐다. 다시 포 그라운드에있는 후 취소 버튼을 누르면 문제가 발생합니다 - 스레드가 취소 된 상태로 반응하지만 즉시 다시 실행되고 끝에 충돌합니다 (Apple 프레임 워크의 어딘가에서 오류 코드가 있음). 응용 프로그램이 전경에 머물러있는 한 스레드를 취소하는 데 완벽하게 작동합니다. 따라서 applicationDidEnterBackground을 입력하면 중단/취소하는 것이 좋습니다. 몇 가지 시도를했지만 각 시도는 그 순간에 작업자 스레드가 일시 중단되었습니다. applicationDidEnterBackground이 호출되었으므로 스레드를 취소하고 기다릴 수 없습니다. 나는 전체 큐 물건 경험 어딘가에 같은 구조를 발견 아니에요
diagView* viewDiagCtrl = startDiag.diagViewControl;
if (viewDiagCtrl != nil && viewDiagCtrl.actionThread != nil)
{
// UIBackgroundTaskIdentifier bgTask is instance variable
NSAssert(self->bgTask == UIBackgroundTaskInvalid, nil);
bgTask = [application beginBackgroundTaskWithExpirationHandler:
^{
dispatch_async(dispatch_get_main_queue(),
^{
NSLog(@"stopping actions definitely");
[viewDiagCtrl stopBackGroundActivity:self];
[application endBackgroundTask:self->bgTask];
self->bgTask = UIBackgroundTaskInvalid;
});
}];
dispatch_async(dispatch_get_main_queue(),
^{
// Start with 10ms time boxes
NSTimeInterval ti = 0.01;
while ([application backgroundTimeRemaining] > 1.0)
{
if (![viewDiagCtrl.actionThread isExecuting])
break;
NSDate* date = [NSDate dateWithTimeIntervalSinceNow:ti];
// Let the current run-loop do it's magif for one time-box.
[[NSRunLoop currentRunLoop] runMode: NSRunLoopCommonModes
beforeDate: date];
// Double the time box, for next try, max out at 1000ms.
ti = MIN(1.0, ti * 2);
}
[viewDiagCtrl stopBackGroundActivity:self];
[application endBackgroundTask:self->bgTask];
self->bgTask = UIBackgroundTaskInvalid;
});
}
: 내가 시도 한 예는 이것이다. 모든 것들이 주 스레드에서 작동하고 작업자 스레드가 일시 중단 된 상태로 남아있어서 취소 할 기회가 없다고 가정합니다. 그와 함께 할 수있는 아이디어가 있습니까?
멀티 스레딩을하지 않고 모든 것을 시도하는 방법에 대해서도 읽었습니다.하지만 정말로 감사하지 않습니다. "배경 이동"상황을 적절하게 처리 할 수있는 유용한 링크가 있습니까?
은 내가 GCD는 네트워크 프로그래밍을하는 가장 좋은 방법은 아니라고 생각. 예를 들어 사용해보십시오. 비동기 적으로 데이터를 다운로드하는 NSURLConnection 대리자 인터페이스 이렇게하면 응용 프로그램의 복잡성이 줄어들고 다중 스레드 프로그래밍의 어려움을 피할 수 있습니다. – Krumelur
아직 NSURLConnection을 사용하지 않았으며 나머지는 모두 완전히 구현되었습니다. 나는 다른 길은 없을 때만이 길로 갈 것입니다. 상황은 프레젠테이션 데이터가 당분간 완전히 유효하지 않기 때문에 전체 업데이트 프로세스에 대한 사용자 I/O를 차단해야한다는 것입니다. 그래서 나는 GUI가 UIAlertView에 의한 업데이트가 필요하고 사용자 상호 작용을 잠그도록 만 허용합니다. 스레드 자체는 [[NSThread alloc] initWithTarget : selector : object :와 함께 생성되며 모든 처리가 정상적으로 작동합니다. – konran