我有一个非常简单的程序,它每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。
感谢。
答案 0 :(得分:0)
仅仅因为你正在使用ARC(总体上这是一件好事)并不意味着你不得不停止考虑内存使用和性能。
在“calcPercent
”方法中,您反复调用“unixSinglePathCommandWithReturn:
”。当你分配了returnValue并设置并退出“while
”循环时,你应该执行“unixTask = nil;
”,这将鼓励ARC正确释放unix任务对象。
另一件事,你每隔两秒就打电话一次。轮询是非常浪费的,所以你应该尝试提出一个更好的方法来做你想做的事情。例如,而不是每两秒钟(当对该函数的多个其他调用可能被卡住或挂起或其他任何情况)时,为什么不在上一次调用“”之后安排事情运行2秒 unixSinglePathCommandWithReturn
“?
b.t.w。,你是一个接一个地分配“unixTask"
(两次单独调用”[NSTask alloc] init]
)。如果这是非ARC代码,那将是一个很大的内存泄漏。就像现在一样,它看起来很糟糕。