私は2 NSOperationsが含まれており、(操作の1つは、標準的な非同時動作である問題キューの同時&非並行NSOperations
1に
setMaxConcurrentOperationCount
を設定することで、次々にそれらを実行するように設定されている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メソッドは時々、新たに追加された操作を呼び出さない。キューにはステータス「実行中」が表示されます。したがって、上記の方法は使用できません。あなたは他の解決策を知っていますか?助けてください.. –