Pergunta

Oi eu tenho o seguinte código:

- (IBAction)runTask:(id)sender {
    NSTask *proc;
    NSPipe *output;
    NSData *data;
    NSString *buffer;

    proc = [[NSTask alloc] init];
    output = [[NSPipe alloc] init];

    [proc setLaunchPath:@"/bin/sh"];
    [proc setArguments:[NSArray arrayWithObjects: @"-c", @"/usr/bin/otool -L /Applications/TextEdit.app/Contents/MacOS/TextEdit | /usr/bin/awk 'NR>1{print $1}' | /usr/bin/sed -e '/@executable_path/d' -e 's/(.*)$//' -e  's/\\/Versions.*$//'", nil]];
    [proc launch];

    data = [[output fileHandleForReading] readDataToEndOfFile];
    buffer = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    NSLog(@"got: %@", buffer);

     // Release
     [proc release];
     [output release];
     [buffer release];
     [data release];
}

O objetivo do Código é meio complicado, ele usa o OTool para obter uma lista das bibliotecas compartilhadas usadas por um binário, e ele usa o Sed e o AWK para filtrá -lo em um formato legível pela máquina. Apenas para testar, usei o binário do Mac OS X Textedit.App.

A questão é que o código é executado e retorna uma saída, mas congela o aplicativo. Eu passei por isso linha por linha e achei essa linha o problema:

dados = [[output fileHandleForReading] readDatatoEndoffile];

Essa linha em si está registrando a saída no console e, em seguida, congelando o aplicativo. Eu verifiquei isso excluindo todas as outras linhas após essa linha e ainda registra a saída e congela. Não há nada no depurador e nenhuma sugestão sobre como resolver esse problema seria muito apreciada.

Foi útil?

Solução 2

A solução para esse problema era simples,

É um bug conhecido que, após o NSTask ser executado, todo o registro não funciona. Ele está retornando uma saída, simplesmente não está registrando -o. A solução foi adicionar esta linha:

[task setStandardInput:[NSPipe pipe]];

E tudo funciona bem :)

Outras dicas

Parece que você está perdendo um

[proc setStandardOutput:output];

Você tem uma barra extra no final da última declaração sed. Depois de removê -lo, o script funciona bem.

A saída deve ser criada com [NSPIPE PIPE] (não de propriedade) e, em seguida, a saída deve ser definida como a saída padrão com [Proc SetStandardOutput: Output

Mas a razão pela qual você está travando é porque você está liberando dados que não alocou, novo ou copiaram. Veja o Regras de gerenciamento de memória.

Veja também Quickies para nstask Para uma boa implementação limpa deste código.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top