2012-07-05 7 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'섹션을 autorelease 풀에 넣어야합니까? 답장을 보내 주셔서 감사합니다. 그것은 올바른 방향으로 나를 가리켰다! – JiuJitsuCoder

관련 문제