나는 객관적입니다. c. 객관적인 C에서 명령 줄 API를 실행하려면 다음 코드를 사용하고 있습니다. 코드가 제대로 작동합니다. 왜이 코드가 NSRunLoop을 사용하고 있습니까?명령 줄 API 및 waitForDataInBackgroundAndNotify
-(void)uploadData
{
setenv([@"PASSWORD" UTF8String], [mPassword UTF8String], 1);
[task setLaunchPath:executablePathRoot];
[task setArguments:array];
NSPipe *pipe = [NSPipe pipe];
NSPipe *errorPipe = [NSPipe pipe];
[task setStandardOutput:pipe];
[task setStandardError:errorPipe];
//keeps your log where it belongs
//[task setStandardInput:[NSPipe pipe]];
NSFileHandle *outFile = [pipe fileHandleForReading];
NSFileHandle *errFile = [errorPipe fileHandleForReading];
[task launch];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(terminated:)
name:NSTaskDidTerminateNotification
object:task];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(outData:)
name:NSFileHandleDataAvailableNotification
object:outFile];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(errData:)
name:NSFileHandleDataAvailableNotification
object:errFile];
[outFile waitForDataInBackgroundAndNotify];
[errFile waitForDataInBackgroundAndNotify];
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
while(!terminated)
{
if (![[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]])
{
break;
}
[pool release];
pool = [[NSAutoreleasePool alloc] init];
}
[pool release];
[self appendDataFrom:outFile to:output];
[self appendDataFrom:errFile to:error];
//[task waitUntilExit];
[task release];
}
-(void) outData: (NSNotification *) notification
{
NSLog(@"outData");
NSFileHandle *fileHandle = (NSFileHandle*) [notification object];
[self appendDataFrom:fileHandle to:output];
[fileHandle waitForDataInBackgroundAndNotify]; //Checks to see if data is available in a background thread.
}
-(void) errData: (NSNotification *) notification
{
NSLog(@"errData");
NSFileHandle *fileHandle = (NSFileHandle*) [notification object];
[self appendDataFrom:fileHandle to:output];
[fileHandle waitForDataInBackgroundAndNotify];
}
- (void) terminated: (NSNotification *)notification
{
NSLog(@"Task terminated");
[[NSNotificationCenter defaultCenter] removeObserver:self];
terminated =YES;
}
실행 루프 코드를 수정 한 것에 동의하지 않습니다. 반복 루프에서 자동으로 생성되고 자동 릴리즈되는 데이터의 양을 모르기 때문에 항상 실행 루프 주위에 자동 복구 풀을 사용해야합니다. 'runMode : beforeDate :'가'NO'를 리턴하면 에러를 나타 내기 때문에 (또는 파이프가 연결되어야하기 때문에 오류 인 입력 소스가 없기 때문에) 루프를 깨는 것이 적절합니다. – ughoavgfhw
@ughoavgfhw 우리가 최적화하려고하는 것을 안다면 autorelease 풀을 사용할 수 있다는 데 동의합니다. 그러나 나는 데이터가 얼마나 생성 될지 모르기 때문에 항상 예방 수단으로 사용하지 않아야한다고 확신합니다. 우리는 이미 현재 쓰레드에 autorelease pool을 가지고있다. – Davyd
@ughoavgfhw 동의합니다. runMode : beforeDate :가 부정적인 결과를 처리해야합니다. – Davyd