まず、キューを作成してから解放するだけではいけません。そのキューをクラスのivarの1つとして作成し、View Controllerがなくなったときにそれを解放する方が自然です(保留中の操作をキャンセルし、実行中の操作が完了するのをキャンセル/待機することもできます)。
次に、操作を作成してキューに追加するメソッドに自動解放プールは必要ありません。これは、そのメソッドがメインスレッドから呼び出されているためです。代わりに、オブジェクトが実際に呼び出すメソッドからの自動解放プールが必要です(これは別のスレッドで実行されている可能性があります)。
したがって、次のようになる可能性があります(キューにivar queue_という名前を付けると仮定します)。
- (void)viewDidLoad
{
[super viewDidLoad];
if( !queue_ ) queue_ = [[NSOperationQueue alloc] init];
// other view loading code
}
- (void)loadData
{
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(firstRun) object:nil];
[queue_ addOperation:operation];
[operation release];
}
- (void)firstRun
{
// Here we may run on another thread, so 1) we need an autorelease pool; and
// 2) we need to make sure we don't do anything that requires a runloop
NSAutoreleasePool* threadPool = [NSAutoreleasePool new];
// do long-running things
[threadPool drain];
}
- (void)dealloc
{
if( queue_ ) {
[queue_ setSuspended:YES];
[queue_ cancelAllOperations];
// you need to decide if you need to handle running operations
// reasonably, but don't wait here because that may block the
// main thread
[queue_ release];
}
// other dealloc stuff
[super dealloc];
}
キューをオンデマンドで初期化することもできるため、viewDidLoadで初期化する代わりに、キューの存在を確認し、必要に応じて、操作を追加する場所で初期化します。これは独自のメソッド呼び出しにラップされている可能性がありますが、キューはかなり軽量であるため、ここでの遅延初期化はおそらく実際には必要ありません。