0

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

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

4

2 回答 2

2

您的代码有几个问题。

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

于 2011-08-26T02:08:55.577 回答