2012-06-22 27 views
1

我有一個非常簡單的程序,它每2秒運行一次腳本並將輸出放入菜單欄項目中。但是,大約90分鐘後,菜單欄項停止更新。任何人都能看到爲什麼簡單的程序在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

要退出它,我只是使用活動監視器將其殺死。內存使用量高於預期(大約30MB),但它真的足以導致應用程序停止?無論哪種方式,我正在運行探查器剛纔檢查泄漏。 –

+0

經過4個半小時沒有停止,它終於做到了。但沒有更多的正常分配,沒有內存泄漏。 –

回答

0

僅僅因爲你使用的ARC(這是一個美妙的事物,總體而言)並不意味着你不得不停止考慮內存使用和性能。

在您的「calcPercent」方法中,您反覆調用「unixSinglePathCommandWithReturn:」。當你得到returnValue分配和設置並跳出你的「while」循環時,你應該執行「unixTask = nil;」這會鼓勵ARC正確釋放unix任務對象。另一件事,你每兩秒鐘就調用一次。輪詢非常浪費,所以你應該嘗試想出一個更好的方法來做你想做的事情。例如,而不是每兩秒鐘(而對該功能的多個其他調用可能卡住或掛起或其他),爲什麼不安排在前面調用「unixSinglePathCommandWithReturn」的結論之後運行2秒

b.t.w.,你一個接一個地分配「unixTask"」(有兩個單獨的電話「[NSTask alloc] init]」)。如果這是非ARC代碼,那將是一個大的內存泄漏。就像現在這樣,它看起來很糟糕。

+0

ARC處理您正確指出的內存「問題」;這些案件都不會泄漏。 –

+0

感謝downvote @BJHomer。也許你對ARC處理雙重''alloc'「&''init'」的東西是正確的(我對ARC還不是很熟悉),但是在非ARC環境中它絕對是一個泄漏,它即使ARC打開,仍然看起來非常糟糕。我們不知道@ Velox的腳本正在做什麼,所以它可能會執行一些耗費大量CPU時間的操作,這意味着多次調用「'unixSinglePathCommandWithReturn」「堆積起來,所以我的建議要回來在重投票(最好做些別的*)應該仍然適用。 –

+0

當然。如果你拿出建議設置爲零會以某種方式幫助ARC,我會刪除downvote。關於投票我們的建議很好。 –