1

我有一个非常简单的程序,它每 2 秒运行一次脚本并将输出放入菜单栏项。但是,大约 90 分钟后,菜单栏项目停止更新。谁能明白为什么?

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    [_window setIsVisible:NO];
    ProcessSerialNumber psn = { 0, kCurrentProcess };
    TransformProcessType(&psn, kProcessTransformToUIElementApplication);
    //the above code stops the dock icon from appearing (and also stops the application from appearing in the alt tab menu

    statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
    [statusItem setHighlightMode:YES];
    [statusItem setTitle:@"0%"]; 
    [statusItem setEnabled:YES];
    [statusItem setToolTip:@"Script output"];

    //[statusItem setAction:@selector(updateIPAddress:)];
    [statusItem setTarget:self];

    //NSString *output = [self unixSinglePathCommandWithReturn:@"/usr/bin/osascript \"/Users/Velox/Projects/Geektool Scripts/WorkDay.scpt\""];

    [NSThread detachNewThreadSelector:@selector(calcPercent) toTarget:[self class] withObject:nil];
}

+(void)calcPercent{
    while(true){
        NSString *output = [self unixSinglePathCommandWithReturn:@"/usr/bin/osascript \"/Users/Velox/Projects/Geektool Scripts/WorkDay.scpt\""];
        [statusItem setTitle:output];
        [statusItem setEnabled:YES];
        [NSThread sleepForTimeInterval:2];
    }
}

+ (NSString *)unixSinglePathCommandWithReturn:(NSString *) command {

    NSPipe *newPipe = [NSPipe pipe];
    NSFileHandle *readHandle = [newPipe fileHandleForReading];
    NSData *inData = nil;
    NSString* returnValue = nil;

    NSTask *unixTask = [[NSTask alloc] init];

    unixTask = [[NSTask alloc] init];
    [unixTask setStandardOutput:newPipe];
    [unixTask setLaunchPath:@"/bin/csh"];
    [unixTask setArguments:[NSArray arrayWithObjects:@"-c", command , nil]]; 
    [unixTask launch];
    [unixTask waitUntilExit];
    //int status = [unixTask terminationStatus];

    while ((inData = [readHandle availableData]) && [inData length]) {

        returnValue= [[NSString alloc] initWithData:inData encoding:[NSString defaultCStringEncoding]];

        returnValue = [returnValue substringToIndex:[returnValue length]-1];

    }

    return returnValue;

}

我正在使用 ARC。

谢谢。

4

1 回答 1

0

仅仅因为您正在使用 ARC(总体而言,这是一件很棒的事情)并不意味着您必须停止考虑内存使用和性能。

在你的 " calcPercent" 方法中,你反复调用 " unixSinglePathCommandWithReturn:"。当您分配 returnValue 并设置并跳出您的“ while”循环时,您应该执行“ unixTask = nil;”,这将鼓励 ARC 正确释放 unix 任务对象。

另一件事,你每两秒调用一次。轮询非常浪费,所以你应该尝试想出一个更好的方法来做你想做的事情。例如,不是每两秒一次(而对该函数的多次其他调用可能会被卡住或挂起或其他),为什么不安排在上一次调用“ ”结束后unixSinglePathCommandWithReturn2 秒运行一次?

顺便说一句,你一个接一个地双重分配 " unixTask"(两次单独调用 " [NSTask alloc] init])。如果这是非 ARC 代码,那将是一个很大的内存泄漏。就像现在一样,它看起来很糟糕。

于 2012-06-22T12:12:34.807 回答