1

So I'm having this issue where once this NSFileHandle/NSPipe gets triggered... my CPU use and memory start going crazy. Problem is I'm finding it hard to find this leak. Any advice or help is appreciated. Cheers.

.h

NSTask *task;
NSPipe *pipe;
NSFileHandle *fileHandle;

@property (weak) IBOutlet NSTextField *commandInputTextField;
@property (unsafe_unretained) IBOutlet NSTextView *nsTastOutput;
@property (weak) IBOutlet NSButton *useOutputSwitch;

.m

- (id)init
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(readPipe:)
                                             name:NSFileHandleReadCompletionNotification
                                           object:nil];
}

- (void)tasker
{   
    task = [[NSTask alloc] init];

    [task setLaunchPath:@"/bin/bash"];

    NSArray *argumentBuilder = [[_commandInputTextField stringValue] componentsSeparatedByString:@" "];

    [task setArguments:argumentBuilder];

    // Pipe output to ScrollView
    if (_useOutputSwitch.state == YES)
    {
        if (!pipe)
        {
            pipe = [[NSPipe alloc] init];
        }

        fileHandle = [pipe fileHandleForReading];
        [fileHandle readInBackgroundAndNotify];

        [task setStandardOutput:pipe];
        [task setStandardError:pipe];
    }

    // Launch task
    [task launch];
}


- (void)readPipe:(NSNotification *)notification
{
    NSData *data;
    NSString *text;

    if( [notification object] != fileHandle )
    {
        return;
    }

    data = [[notification userInfo] objectForKey:NSFileHandleNotificationDataItem];
    text = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];

    NSScroller *scroller = [[_nsTastOutput enclosingScrollView] verticalScroller];
    BOOL shouldScrollToBottom = [scroller doubleValue] == 1.0;
    NSTextStorage *ts = [_nsTastOutput textStorage];
    [ts replaceCharactersInRange:NSMakeRange([ts length], 0) withString:text];
    if (shouldScrollToBottom)
    {
        NSRect bounds = [_nsTastOutput bounds];
        [_nsTastOutput scrollPoint:NSMakePoint(NSMaxX(bounds), NSMaxY(bounds))];
    }

    if (data != 0)
    {
        [fileHandle readInBackgroundAndNotify];
    }
}
crewshin
  • 765
  • 9
  • 22
  • You might consider replacing your NSNotification-based code with a [readability handler block](http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSFileHandle_Class/Reference/Reference.html#//apple_ref/occ/instp/NSFileHandle/readabilityHandler). As for the resource consumption problem(s), run your app under Instruments, using Time Profiler to profile CPU usage and the Leaks template to profile memory usage. – Peter Hosey Jul 30 '12 at 07:54
  • Ah thanks for the tip about readability handler block. I'll read up on that. I've tested with instruments quite a bit which is how I know I have this issue... I just can't seem to track down what I'm doing wrong however. Thanks again. – crewshin Jul 30 '12 at 16:55
  • The Time Profiler and Allocations instruments each provide a call tree showing how much time/memory is being used by every part of your program (including framework code). The Leaks instrument will give you a list of every leaked object (not including “abandoned” objects that you're still holding onto but not using). – Peter Hosey Jul 30 '12 at 17:59
  • I resurrected this with an updated thread -- did you you ever resolve the issue? https://stackoverflow.com/questions/44833266/how-to-terminate-all-threads-reading-from-pipe-nspipe-related-to-process-nsta – wcochran Jun 29 '17 at 19:25

1 Answers1

1

I met a similar problem while using the readabilityHandler. I finally find out closing the fileHandle after task complete resolves the problem. Wish it helps your case.

Wei Wei
  • 11
  • 1