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