【问题标题】:Can someone help me spot a leak in this NSPipe/NSFileHandle code?有人可以帮我发现这个 NSPipe/NSFileHandle 代码中的漏洞吗?
【发布时间】:2012-07-29 23:07:59
【问题描述】:

所以我遇到了这个问题,一旦这个 NSFileHandle/NSPipe 被触发......我的 CPU 使用和内存开始变得疯狂。问题是我发现很难找到这个泄漏。任何建议或帮助表示赞赏。干杯。

.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];
    }
}

【问题讨论】:

  • 你可以考虑用readability handler block替换你的基于NSNotification的代码。至于资源消耗问题,请在 Instruments 下运行您的应用,使用 Time Profiler 分析 CPU 使用情况,使用 Leaks 模板分析内存使用情况。
  • 谢谢关于可读性处理程序块的提示。我会阅读的。我已经用仪器进行了很多测试,这就是我知道我有这个问题的方式......但是我似乎无法追踪我做错了什么。再次感谢。
  • 时间分析器和分配工具每个都提供一个调用树,显示程序的每个部分(包括框架代码)正在使用多少时间/内存。泄漏工具将为您提供每个泄漏对象的列表(不包括您仍然持有但未使用的“废弃”对象)。
  • 我用一个更新的线程复活了这个问题——你有没有解决过这个问题? stackoverflow.com/questions/44833266/…

标签: objective-c cocoa nstask nsfilehandle nspipe


【解决方案1】:

我在使用 readabilityHandler 时遇到了类似的问题。我终于发现在任务完成后关闭 fileHandle 解决了问题。希望它对您的情况有所帮助。

【讨论】:

  • 我注意到这降低了 CPU 使用率,但相关线程似乎没有终止。
猜你喜欢
  • 1970-01-01
  • 2023-03-06
  • 2016-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-26
  • 2021-12-24
  • 1970-01-01
相关资源
最近更新 更多