I 2 NSOperations를 포함하고 (동작들의문제 큐 동시 및 비 동시 NSOperations
하나는 표준 비 동시 운전이 setMaxConcurrentOperationCount
1로 설정하여 다른 후에 하나를 수행하도록 설정하는 NSOperationQueue을 그냥 main
메소드). 웹에서 일부 데이터를 동 기적으로 검색합니다 (당연히 별도의 연산 스레드에서). 비동기 적으로 실행해야하는 코드를 사용해야하므로 다른 작업은 동시 작업입니다.
문제는 동시 작업이 큐에 먼저 추가 된 경우에만 작동한다는 것을 발견했습니다. 어떤 동시 작업이 아닌 경우에는 이상하게도 start
메서드가 제대로 호출되지만 메서드가 끝난 후 콜백 메서드에 대한 연결을 설정하면 절대 수행되지 않습니다. 큐에서 더 이상의 조작이 수행되지 않습니다. 마치 start 메소드가 반환 된 후 멈추는 것처럼 보이며, 어떤 URL 연결의 콜백도 호출되지 않습니다!
동시 작업을 처음 대기열에 넣으면 모든 것이 올바르게 작동하고 비동기 콜백이 작동하고 완료된 후 후속 작업이 실행됩니다. 나는 전혀 이해하지 못한다!
아래의 동시 병행 NSOperation에 대한 테스트 코드를 볼 수 있으며, 솔리드임을 확신 할 수 있습니다.
도움이 될 것입니다.
메인 스레드 관측 :
난 그냥 동시 작업이 큐에 첫 번째 경우 다음 [start]
방법은 주 스레드에서 호출되는 것을 발견했다. 그러나 큐에 처음으로 없으면 (동시 또는 비 동시 발생 이후), [start]
메소드는 주 스레드에서 호출되지 않습니다. 이것은 내 문제의 패턴에 맞는 것처럼 중요해 보입니다. 이것에 대한 이유는 무엇일까요?
동시 NSOperation 코드 :
@interface ConcurrentOperation : NSOperation {
BOOL executing;
BOOL finished;
}
- (void)beginOperation;
- (void)completeOperation;
@end
@implementation ConcurrentOperation
- (void)beginOperation {
@try {
// Test async request
NSURLRequest *r = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.google.com"]];
NSURLConnection *c = [[NSURLConnection alloc] initWithRequest:r delegate:self];
[r release];
} @catch(NSException * e) {
// Do not rethrow exceptions.
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(@"Finished loading... %@", connection);
[self completeOperation];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(@"Finished with error... %@", error);
[self completeOperation];
}
- (void)dealloc {
[super dealloc];
}
- (id)init {
if (self = [super init]) {
// Set Flags
executing = NO;
finished = NO;
}
return self;
}
- (void)start {
// Main thread? This seems to be an important point
NSLog(@"%@ on main thread", ([NSThread isMainThread] ? @"Is" : @"Not"));
// Check for cancellation
if ([self isCancelled]) {
[self completeOperation];
return;
}
// Executing
[self willChangeValueForKey:@"isExecuting"];
executing = YES;
[self didChangeValueForKey:@"isExecuting"];
// Begin
[self beginOperation];
}
// Complete Operation and Mark as Finished
- (void)completeOperation {
BOOL oldExecuting = executing;
BOOL oldFinished = finished;
if (oldExecuting) [self willChangeValueForKey:@"isExecuting"];
if (!oldFinished) [self willChangeValueForKey:@"isFinished"];
executing = NO;
finished = YES;
if (oldExecuting) [self didChangeValueForKey:@"isExecuting"];
if (!oldFinished) [self didChangeValueForKey:@"isFinished"];
}
// Operation State
- (BOOL)isConcurrent { return YES; }
- (BOOL)isExecuting { return executing; }
- (BOOL)isFinished { return finished; }
@end
큐 코드
// Setup Queue
myQueue = [[NSOperationQueue alloc] init];
[myQueue setMaxConcurrentOperationCount:1];
// Non Concurrent Op
NonConcurrentOperation *op1 = [[NonConcurrentOperation alloc] init];
[myQueue addOperation:op1];
[op1 release];
// Concurrent Op
ConcurrentOperation *op2 = [[ConcurrentOperation alloc] init];
[myQueue addOperation:op2];
[op2 release];
나는 또한이 동일한 문제점을 가지고있다. 하지만 제 경우에는 start 메서드가 때때로 새로 추가 된 작업을 요구하지 않습니다. 대기열에는 여전히 '실행 중'상태가 표시됩니다. 그래서 위의 방법은 사용할 수 없습니다. 다른 해결책을 알고 있습니까? 도와주세요.. –