簡體   English   中英

在Objective-C的循環中運行NSTask

[英]Running NSTask inside a loop in Objective-C

我試圖運行一個簡單的shell命令,該命令在NSArray生成的編譯時在不確定大小的循環內相當快地運行並返回文本。 在像perl這樣的腳本語言中,我將能夠執行以下操作:

for(i=0;i<=$myinputarraysize;i++){
    $output[i]=`/my/task $inputarray[i]`;
}

這將從任務的預期輸出為我構建一個新數組。 在Obj-C中,這似乎要困難得多,並且讓我感到困惑。 現在我的循環看起來像這樣:

for(int i=0; i<[inputarray count]; i++){
    NSTask *task;
    task = [[NSTask alloc] init];
    [task setLaunchPath:nsdchat];

    NSArray *args;
    args = [NSArray arrayWithObjects:@"/my/task", [inputarray objectAtIndex:i], nil];
    [task setArguments:args];

    NSPipe *pipe;
    pipe = [NSPipe pipe];
    [task setStandardOutput:pipe];

    NSFileHandle *file;
    file = [pipe fileHandleForReading];

    [task launch];

    NSData *data;
    data = [file readDataToEndOfFile];

    NSString *desc;
    desc = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];    
    desc = [string stringByReplacingOccurrencesOfString:@"\n" withString:@""];

    [descriptions insertObject:desc atIndex:i];

    [task release];
    [args release];
    [pipe release];
    [file release];
    [data release]; 
}

我的目標是用任務的輸出(我知道總是一個字符串,並且總是以我要刪除的換行符結尾)填充描述(一個NSMutableArray)。 似乎我缺少有關內存釋放的信息,因為當我運行此命令並輸出NSLog時,整個循環的計數結果相同。

有沒有更簡單或更簡單的方法循環遍歷這樣的簡單任務? 我是否為自己過於復雜?

首先,不需要在循環內完成大部分工作。 taskpipefile看起來都可以在循環外處理。 您還應該考慮使用Objective-C 2.0點語法和快速枚舉來減少一些麻煩。

更重要的是:

NSArray *args;
args = [NSArray arrayWithObjects:@"/my/task", [inputarray objectAtIndex:i], nil];
[task setArguments:args];

這表示傳遞到路徑ndschat的可執行文件的第一個參數是/my/task 這似乎與您的PERL使用情況不符。 可能您只想:

NSArray *args;
args = [NSArray arrayWithObject:[inputarray objectAtIndex:i]];
[task setArguments:args];

或者,考慮到樣式注釋:

for(NSString *argument in inputarray)
{
    ...
    task.arguments = [NSArray arrayWithObject:argument];
    ...
}

編輯:您還釋放了許多您不擁有的對象,以及在代碼中增加大量內容是可能導致崩潰的內存管理錯誤。 因此,要減少整個故障並糾正該故障:

for(NSString *argument in inputarray)
{
    NSTask *task = [[NSTask alloc] init];  // you now own this
    task.launchPath = nsdchat;

    NSPipe *pipe = [NSPipe pipe];          // you don't own this
    task.standardOutput = pipe;

    NSFileHandle *file = [pipe fileHandleForReading];  // you also don't own this

    task.arguments = [NSArray arrayWithObject:argument];
    [task launch];
    [task waitUntilExit]; // you should wait until the task is done

    NSData *data = [file readDataToEndOfFile];  // this is another thing
                                                // you don't own. Note also that
                                                // readDataToEndOfFile advances
                                                // the current read pointer, so
                                                // it should be fine to do this
                                                // successively 

    NSString *desc;
    desc = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] 
                                                                   autorelease];    
                                                // you don't own this because
                                                // of the autorelease; you
                                                // don't want to own it since
                                                // the next line will throw
                                                // it away


    desc = [string stringByReplacingOccurrencesOfString:@"\n" withString:@""];
                                                // you don't own this

    [descriptions addObject:desc];
    [task release];
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM