【问题标题】:NSSavePanel issuesNSSavePanel 问题
【发布时间】:2011-08-26 02:05:43
【问题描述】:

我是可可编程的半新手,但是我在 C++ 中工作过很多;

我在使用 NSSavePanel 类时遇到了一些问题。每当我使用它时(如下所示),我可以看到(通过使用断点)代码尝试执行结束括号。然后我在 main.h 文件中从 Xcode 获得 BAD_ACCESS 消息。我一生都无法弄清楚我做错了什么。代码如下:

- (void)scannerDevice:(ICScannerDevice*)scanner didCompleteScanWithError:(NSError*)error;
{
    NSLog( @"scannerDevice: \n%@\ndidCompleteScanWithError: \n%@\n", scanner, error );
    [mProgressIndicator setHidden:YES];

    NSSavePanel *savePopup = [[NSSavePanel alloc]init];
    [savePopup runModal];

    NSMutableString *saveString = [[NSString alloc] init];
    saveString = [[savePopup URL] absoluteString];
    [saveString deleteCharactersInRange:NSMakeRange(0, 16)];
    [saveString appendString:@".jpeg"];

    NSLog(@"[[ADDRESS: %@", saveString); //Outputs /Users/tannerdsilva/Documents/TestFolder/NewName.jpeg
    NSError *errorSave = [[NSError alloc] init];

    [manager moveItemAtPath:[@"~/Foo.jpeg" stringByExpandingTildeInPath] toPath:[[savePopup URL] absoluteString] error:&errorSave]; // ~/Foo.jpeg does exist

    NSLog(@"ERROR: %@", errorSave);
    [saveString dealloc];
    [savePopup dealloc];

}

当我对新目的地进行硬编码并删除 NSSavePanel 时,我没有遇到任何崩溃。

提前感谢您,如果这是一个简单的修复,我深表歉意。

【问题讨论】:

    标签: objective-c xcode nssavepanel


    【解决方案1】:

    您的代码存在几个问题。

    • 您将saveString 声明为NSMutableString,但将其初始化为(不可变)NSString
    • 然后您根本不使用该字符串,而是将其替换为从 absoluteString 返回的自动释放(且不可变)NSString,从而导致原始字符串泄漏。
    • NSString 既不响应 deleteCharactersInRange: 也不响应 appendString(这些是 NSMutableString 的方法)。
    • 您正在泄漏 errorSave,无论如何您都应该将其初始化为 nil
    • 你应该永远自己打电话给dealloc,改用release。但是不要释放saveString,因为它已经被自动释放(见上文),你在这里过度释放它,当自动释放池耗尽时会导致崩溃。

    【讨论】:

      【解决方案2】:

      好的,您的代码有几个问题:


      方法签名有一个尾随分号

      (void)scannerDevice:(ICScannerDevice*)scanner didCompleteScanWithError:
          (NSError*)error;
      

      编辑:根据@omz 和@Rudy Velthuis,Objective-C 允许在实现方法签名上使用尾随分号。所以你可以忽略这个“问题”。


      你应该使用类实例来获取保存面板的句柄

      NSSavePanel * savePanel = [NSSavePanel savePanel];
      

      您应该检查模式运行保存面板的结果

      if ([savePanel runModal] == NSOKButton) {
          //...
      }
      

      *你正在创建一个 NSString * 的实例并泄露它,完全没有必要*

      NSMutable * saveString = [NSMutableString stringWithString: 
         [[savePopup URL] absoluteString]];
      

      一旦您纠正了上述问题,您将需要删除两个 dealloc 行,因为这些对象现在将被自动释放。请注意,您通常希望在代码中调用 release,而不是 dealloc

      【讨论】:

      • 这不是语法错误。事实上,在签名的末尾加上分号更方便,因为它可以通过这种方式原样复制到头部。
      • 允许使用那些浮动分号,因为它使从 @interface 部分复制和粘贴变得更加容易。
      • @omz:或者反过来:from 标题。我一般先写header。
      • @Rudy:对,从标题复制可能更常见。
      • 有趣,我猜你每天都会学到一些新东西。我无法想象以这种方式在我的实现文件中编写方法签名,它激怒了我内心的 C 编码器。
      猜你喜欢
      • 2023-04-07
      • 1970-01-01
      • 2021-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多