objective-c - 简单的程序在 90 分钟左右后停止

标签 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。

谢谢。

最佳答案

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

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

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

b.t.w.,您正在双重分配“unixTask”(两次单独调用“[NSTask alloc] init])。如果这是非- ARC 代码,这将是一个很大的内存泄漏。就目前而言,它看起来很糟糕。

关于objective-c - 简单的程序在 90 分钟左右后停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11153401/

相关文章:

Python 在 Mac OS X 上诅咒鼠标事件

php - 在 Mac OS X Yosemite 中发送邮件

objective-c - 可拖动的 NSButton

objective-c - 如何让插件导入 UTI 类型

objective-c - Objective C 中的声明类型与实际类型

ios - 在另一个定义中使用台风组装模型属性

ios - 如何在 iOS 中创建 365 天的本地通知

iphone - 由于获取的结果 Controller 更新,释放的 View Controller 导致 EXC_BAD_ACCESS

objective-c - NSAppleScript 使用给定的 NSRange 突出显示任何 Mac 应用程序中的文本

objective-c - 如何获取 NSOutLineView 中的特定项目?