好的,我遇到了一個內存管理問題,它將我推上了一堵牆。有一次,我發誓這沒有問題,但現在它泄漏內存到處都是,我找不出原因。難以忍受OS X的內存泄漏應用程序
首先我開始一個NSTask,然後在任務運行時運行一個循環。
NSTask *encodingTask = [[NSTask alloc] init];
NSFileHandle *taskStdout = [NSFileHandle fileHandleForWritingAtPath:encodingOutput];
[encodingTask setStandardOutput:taskStdout];
[encodingTask setStandardError:taskStdout];
NSString argString = [NSString stingWithString: @"some arguments"];
[encodingTask setArguments:taskArgs];
[encodingTask setLaunchPath:somePath];
[encodingTask launch];
while ([encodingTask isRunning]){
sleep(1);
[self encodeProgressTimer];
}
的encodeProgessTimer方法抓住從標準輸出的最後一行,並把在菜單欄:
- (void)encodeProgressTimer
{
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"menuProgress"]) {
// Read the last line
NSString *fileData = [NSString stringWithContentsOfFile:encodingOutput encoding:NSASCIIStringEncoding error:nil];
NSArray *lines = [fileData componentsSeparatedByString:@"\r"];
NSString *lastLine = [lines objectAtIndex:[lines count] - 1];
NSString *percent;
NSString *eta;
BOOL dataFound = NO;
if ([lastLine length] == 71) {
dataFound = YES;
percentRange = (NSRange) {23,5};
etaRange = (NSRange) {61,9};
percent = [lastLine substringWithRange:percentRange];
eta = [lastLine substringWithRange:etaRange];
}
else if ([lastLine length] == 72) {
dataFound = YES;
percentRange = (NSRange) {23,5};
etaRange = (NSRange) {62,9};
percent = [lastLine substringWithRange:percentRange];
eta = [lastLine substringWithRange:etaRange];
}
else if ([lastLine length] == 70) {
dataFound = YES;
percentRange = (NSRange) {23,5};
etaRange = (NSRange) {60,9};
percent = [lastLine substringWithRange:percentRange];
eta = [lastLine substringWithRange:etaRange];
}
if (dataFound) {
NSMutableString *bottomStr = [[NSMutableString alloc]
initWithFormat:@"Encoding: %@%% - ETA %@", percent, eta];
[appDelegate setMenuTop:topString andBottom:bottomStr];
[bottomStr release];
}
}
}
這是我的理解是什麼,我沒有具體分配和初始化應該在方法完成時自動釋放,但事實並非如此。當被調用時,內存使用量每秒呈指數增長。如果我看看我的記憶分配,那麼活着的CFstings的數量將通過屋頂。如果我打開encodeProgressTimer,我的問題就會消失。我嘗試添加一個自動釋放池來編碼使內存使用非常穩定的ProgressTimer,但是在運行20分鐘左右後,我得到一個EXC_BAD_ACCESS。打開殭屍原來是成:
*** -[NSConcreteAttributedString _drawCenteredVerticallyInRect:scrollable:]: message sent to deallocated instance 0x2bc756e0
其實我去通過,並改變每個變量聲明爲它分配/初始化配對,並手動將其釋放,但它還是不解決問題。在這一點上,我很難過。
而且爲了完整起見,[的appDelegate setMenuTop:andBottom:]方法是這樣的:
-(void) setMenuTop: (NSString *) top andBottom: (NSString *) bottom
{
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"menuProgress"]) {
[statusItem setImage:nil];
NSMutableParagraphStyle *lineHeight = [[NSMutableParagraphStyle alloc] init];
[lineHeight setMaximumLineHeight:10.5];
[lineHeight setLineBreakMode:NSLineBreakByTruncatingMiddle];
OperationQueue *opQueue = [OperationQueue sharedQueue];
NSString *sBuffer = [[NSMutableString alloc] initWithFormat: @"%@ (%i More)\n%@", top, [opQueue queueCount] - 1, bottom];
attributes = [[NSDictionary alloc] initWithObjectsAndKeys:[NSFont menuFontOfSize:9], NSFontAttributeName, lineHeight, NSParagraphStyleAttributeName, nil];
if (statusTitle)
[statusTitle release];
statusTitle = [[NSAttributedString alloc] initWithString: sBuffer attributes: attributes];
[statusItem setAttributedTitle: statusTitle];
[lineHeight release];
[sBuffer release];
[attributes release];
}
}
這就是它!當我把NSAutoReleasePool放入並且仍然崩潰時,我認爲它仍然是一個內存管理問題。原來我還需要在主線程中運行狀態欄更新。現在一切似乎都順利運行,非常感謝! – Kris