NSInvocationOperation
操作用の自動解放プールを作成するかどうかをテストするための小さなプログラムを作成しました。
#import <Foundation/Foundation.h>
@interface MyClass : NSObject
@end
@implementation MyClass
- (void)performSomeTask:(id)data
{
NSString *s = [[[NSString alloc] initWithFormat:@"hey %@", data]
autorelease];
if ([[NSThread currentThread] isMainThread])
NSLog(@"performSomeTask on the main thread!");
else
NSLog(@"performSomeTask NOT on the main thread!");
NSLog(@"-- %@", s);
}
@end
int main(int argc, char *argv[]) {
MyClass *c = [MyClass new];
if (argc == 2 && strcmp(argv[1], "nop") == 0)
[c performSomeTask:@"ho"];
else {
NSInvocationOperation *op = [[NSInvocationOperation alloc]
initWithTarget:c
selector:@selector(performSomeTask:)
object:@"howdy"];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:op];
[op waitUntilFinished];
[op release];
[queue release];
}
[c release];
return 0;
}
これは次のように機能します。コマンドラインで「nop」が渡される-performSomeTask:
と、自動解放プールが設定されていない状態で、メインスレッドで直接実行されます。結果の出力は次のとおりです。
$ ./c nop
*** __NSAutoreleaseNoPool(): Object 0x10010cca0 of class NSCFString autoreleased with no pool in place - just leaking
performSomeTask on the main thread!
-- hey ho
自動解放された文字列が-performSomeTask:
リークの原因になります。
「nop」を渡さずにプログラムを実行する-performSomeTask:
とNSInvocationOperation
、別のスレッドでが実行されます。結果の出力は次のとおりです。
$ ./c
*** __NSAutoreleaseNoPool(): Object 0x100105ec0 of class NSInvocation autoreleased with no pool in place - just leaking
*** __NSAutoreleaseNoPool(): Object 0x100111300 of class NSCFSet autoreleased with no pool in place - just leaking
*** __NSAutoreleaseNoPool(): Object 0x100111b60 of class NSCFSet autoreleased with no pool in place - just leaking
*** __NSAutoreleaseNoPool(): Object 0x100105660 of class NSCFSet autoreleased with no pool in place - just leaking
performSomeTask NOT on the main thread!
-- hey howdy
ご覧のとおり、リークしているとのインスタンスがNSInvocation
ありますが、の自動解放された文字列はリークしていないため、その呼び出し操作用に自動解放プールが作成されました。NSSet
-performSomeTask:
NSInvocationOperation
並行性プログラミングガイドがカスタムサブクラスについて提案しているように、 (そしておそらくAppleのフレームワークのすべてのNSOperation
サブクラスが)独自の自動解放プールを作成すると仮定するのは安全だと思いますNSOperation
。