简单程序在90分钟左右后停止

时间:2012-06-22 09:17:10

标签: objective-c macos cocoa

我有一个非常简单的程序,它每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。

感谢。

1 个答案:

答案 0 :(得分:0)

仅仅因为你正在使用ARC(总体上这是一件好事)并不意味着你不得不停止考虑内存使用和性能。

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

另一件事,你每隔两秒就打电话一次。轮询是非常浪费的,所以你应该尝试提出一个更好的方法来做你想做的事情。例如,而不是每两秒钟(当对该函数的多个其他调用可能被卡住或挂起或其他任何情况)时,为什么不在上一次调用“”之后安排事情运行2秒 unixSinglePathCommandWithReturn“?

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