objective-c - NSError 不会清除旧错误

标签 objective-c cocoa

长期倾听者,第一次来电,如果我不够明确,请原谅我。我目前正在为 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;
   }
}

最佳答案

我怀疑问题出在 popupWithErrorMessage 中,它堆积了本地化描述。即使 NSError 对象的生命周期中存在错误,为单独的错误创建的每个对象都是一个单独的对象,并且不会将其他 NSError 对象的本地化描述填充到其中。另一方面,您对 popupWithErrorMessage 的描述听起来很可疑:[popupView orderOut:self] 只是从屏幕上删除窗口,但不会释放它或导致它被销毁。您可以发布 popupWithErrorMessage 的代码吗?

关于objective-c - NSError 不会清除旧错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11338107/

相关文章:

objective-c - 为什么 NSSet objectEnumerator 会增加保留计数?

iphone - 解析 RSS 提要的主体

cocoa - 给 NSWindow 一个背景图片

macos - NSWindowDidBecomeMainNotification 为所有窗口触发

objective-c - 释放使用 initWithInteger : vs. numberWithInt 创建的 NSNumber 实例:

ios - NSDictionary 在推送通知中返回空字符串

iphone - Xamarin iTunes 附属链接

objective-c - 将 CAMediaTimingFunction 与基于 block 的 UIView 动画一起使用

macos - 大量混合数据用什么格式存储

macos - 获取双击启动 macOS 应用程序的文件名