2012-07-05 36 views
0

長時間的聽衆,第一次打電話給我,如果我不夠明確,請原諒我。我目前正在用NSError對象來解決問題。這是怎麼回事兒設置:NSError不會清除舊的錯誤

-(void)mainMethod { 
    NSError *myError = nil; 
    NSString *myString = @"A really great string. 1234."; 
    if ([self parseAndStoreString:myString error:&myError] == NO) { 
     [self popupWithErrorMessage:[[myError localizedDescription] copy]]; 
    } 

-(BOOL)parseAndStoreString:(NSString *)incomingString error:(NSError *__autoreleasing *)err { 
    if ([self setupSomething error:err] == NO) { 
     return NO; 
    } 
    if ([self doSomethingWithString:incomingString error:err] == NO) { 
     return NO; 
    } 
    if ([self storeString:incomingString error:err] == NO) { 
     return NO; 
    } 
} 

-(BOOL)doSomethingWithString:(NSString *)incomingString error:(NSError *__autoreleasing *)err { 
    if (incomingString == nil) { 
    DLog(@"String was null! See? : %@", incomingString); 
    NSDictionary *errorInfo = [NSDictionary dictionaryWithObject:EDEmptyStringErrorDescription forKey:NSLocalizedDescriptionKey]; 
    if (err != nil) *err = [NSError errorWithDomain:EDStringDomain code:EDEmptyStringError userInfo:errorInfo]; 
    return NO; 
    } 
    if (somethingElseIsWrongWithString) { 
    DLog(@"Another Problem Geesh"); 
    NSDictionary *errorInfo = [NSDictionary dictionaryWithObject:EDAnotherStringErrorDescription forKey:NSLocalizedDescriptionKey]; 
    if (err != nil) *err = [NSError errorWithDomain:EDStringDomain code:EDAnotherStringError userInfo:errorInfo]; 
    return NO; 
    } 
} 

現在哪個錯誤命中通過預計在第一時間被適當建立並顯示在彈出。當用戶點擊某個可再次激活'mainMethod'的方法或調用'parseAndStoreString:error:'(有三個或四個調用方法)的方法時,問題就出現了。如果還有其他錯誤,則彈出窗口顯示第一個錯誤的描述,第二個錯誤粘合到一個字符串中。這是ARC代碼,所以我的理解是編譯器應該在出現錯誤後釋放myError對象(或其他方法創建的任何NSError對象)。我不認爲問題出現在'popupWithErrorMessage'方法中,因爲我只傳入了本地化描述的副本,該副本被顯示並由[popupView orderOut:self]銷燬。有關這些錯誤消息如何在NSError對象中堆積如山的任何想法?

@ torrey.lyons:當然,這裏是togglePopupWithMessage代碼:onView-

- (void)popupWithErrorMessage:(NSString *)errorToDisplay { 
    if (!messagePopup) { 
     if (errorToDisplay == nil) { 
     DLog(@"Warning, incoming error message was nil"); 
     return; 
     } 

     NSDictionary *messageAttributes = [NSDictionary dictionaryWithObjectsAndKeys: 
            [NSColor whiteColor], NSForegroundColorAttributeName, 
            [NSFont systemFontOfSize:12], NSFontAttributeName, 
            nil]; 
     NSAttributedString *messageWithAttributes = [[NSAttributedString alloc] 
                initWithString:errorToDisplay 
                attributes:messageAttributes]; 

     NSPoint messagePoint = NSMakePoint(NSMidX([[self.mainSplitView.subviews objectAtIndex:1] frame]), 
             NSMinY([anchorView frame])+4.0f); 
     messagePopup = [[MAAttachedWindow alloc] initWithView:popupView 
              attachedToPoint:messagePoint 
                inWindow:[self window] 
                onSide:MAPositionBottom 
               atDistance:0]; 
     [messagePopup setAlphaValue:0.0f]; 

     NSTextStorage *messageStorage = popupMessage.textStorage; 
     [messageStorage beginEditing]; 
     [messageStorage insertAttributedString:messageWithAttributes atIndex:0]; 
     [messageStorage endEditing]; 

     [messagePopup setFrame:NSMakeRect(messagePopup.frame.origin.x, messagePopup.frame.origin.y, 250.0f, 100.0f) 
        display:YES]; 

     messageWithAttributes = nil; 
     messageAttributes = nil; 
     errorToDisplay = @""; 

     [[self window] addChildWindow:messagePopup ordered:NSWindowAbove]; 


     [[messagePopup animator] setAlphaValue:1.0f]; 
     [popupMessage setNeedsDisplay:YES]; 

     [NSTimer scheduledTimerWithTimeInterval:3.5 
             target:self 
            selector:@selector(turnOffPopupFromTimer:) 
            userInfo:nil 
             repeats:NO]; 
    } else { 
     [[self window] removeChildWindow:messagePopup]; 
     [messagePopup fadeOutAndOrderOut:YES]; 
     messagePopup = nil; 
    } 
- (void)turnOffPopupFromTimer:(NSTimer *)timer { 
    if (messagePopup) {    
            //Added to correct problem \/\/\/\/ 
     NSTextStorage *messageStorage = popupMessage.textStorage; 
     [messageStorage beginEditing]; 
     [messageStorage deleteCharactersInRange:NSMakeRange(0, messageStorage.characters.count)]; 
     [messageStorage endEditing]; 
            //Added to correct problem /\/\/\/\ 
     [[self window] removeChildWindow:messagePopup]; 
     [messagePopup fadeOutAndOrderOut:YES]; 
     messagePopup = nil; 
    } 
} 
+0

如果記錄錯誤以顯示在popupWithErrorMessage方法的開頭,會發生什麼情況? –

+0

@JesseRusak,正如我深入探討'popupWithErrorMessage:''NSTextStorage'對象保留舊文本一樣。我錯誤地認爲'NSTextStorage'對象是由ARC發佈的,因此當彈出窗口被命令並設置爲nil時會被殺死。即使代碼現在正在工作,我仍然不明白爲什麼它被保留。 – JiuJitsuCoder

回答

1

我懷疑問題出在popupWithErrorMessage,這是堆放本地化描述。即使NSError對象的生命週期中存在一個錯誤,爲每個錯誤創建的每個錯誤都是一個單獨的對象,並且不會有其他NSError對象的本地化描述。另一方面,您對popupWithErrorMessage的描述聽起來很可疑:[popupView orderOut:self]只是將窗口從屏幕上移除,但不會釋放它或導致它被破壞。你能發佈popupWithErrorMessage的代碼嗎?

+0

我在回答中添加了'popupWithErrorMessage'代碼。我今天早上醒來時以爲我可能錯了,而且問題可能發生在popupWithErrorMessage中。我認爲如果主窗口被淘汰,它應該銷燬其中包含的任何對象。我添加了評論文本到'turnOffPopup'方法,它似乎工作正常。我仍然對編譯器保留對象的原因感到困惑。 'textStorage'部分應該放在自動釋放池中嗎?感謝您的回覆。它指出我在正確的方向! – JiuJitsuCoder