NSSavePanel问题

时间:2011-08-26 02:05:44

标签: objective-c xcode nssavepanel

我是可可编程的半新手,但是我在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时,我没有遇到任何崩溃。

提前感谢您,如果这是一个简单的解决方案,我道歉。

2 个答案:

答案 0 :(得分:2)

您的代码存在一些问题。

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

答案 1 :(得分:1)

好的,您的代码存在一些问题:


方法签名有一个尾部分号

(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