나는 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"을 전달하지 않고 프로그램을 실행하면 다른 스레드의 NSInvocationOperation
을 통해 -performSomeTask:
이 실행됩니다. 결과 출력은 :
우리가 알 수 있듯이,
누출되지만 -performSomeTask:
에서 오토 릴리즈 문자열 누출되지
NSInvocation
및
NSSet
의 인스턴스가
$ ./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
, 따라서 오토 릴리즈 풀 그 호출 동작 작성된 .
가 나는 NSInvocationOperation
(애플의 프레임 워크와 probally 모든 NSOperation
서브 클래스)는 동시성 프로그래밍 가이드는 사용자 정의 NSOperation
서브 클래스 제안처럼, 자신의 오토 릴리즈 풀을 만들 수 있다고 가정하는 것이 안전합니다 생각합니다.
iOS 3.x에서 테스트 했습니까? 여기에 설명 된대로 GCD 구현 세부 사항이 될 수 있습니다. http://stackoverflow.com/questions/4141123/do-you-need-to-create-an-nsautoreleasepool-within-a-block-in-gcd – Danra
@Danra AFAICT NSOperationQueue는 GCD를 사용하지 않습니다. 또한 위의 코드를'[op start]'를 통해 동 기적으로 실행하도록 변경하면 문자열이 누수되었음을 나타내는 메시지가 표시되지 않습니다. 즉, NSInvocationOperation이 조작을위한 자동 해제 풀을 생성합니다. –
@Danra Mac OS 10.6.6에서만이 동작을 테스트했습니다. –