开发者

NSSavePanel issues

I am semi-new to cocoa programming, however I have worked quite a bit in C++;

I am having some issues with the NSSavePanel class. Whenever I use it (as shown below), I can see (by using breakpoints) that the code tries to execute the ending bracket. I then get a BAD_ACCESS message from Xcode in the main.h file. I cannot for the life of me figure out what I am doing wrong. Here is the code:

- (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 exis开发者_开发百科t

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

}

When I hard code the new destination and remove the NSSavePanel, I don't get any crashes.

Thank you ahead of time, and I apologize if this is a simple fix.


There are a couple of issues with your code.

  • You declare saveString as an NSMutableString but initialize it as an (immutable) NSString.
  • You're then not using that string at all but replace it with the autoreleased (and immutable) NSString that's returned from absoluteString, causing the original string to leak.
  • NSString responds to neither deleteCharactersInRange: nor to appendString (those are methods of NSMutableString).
  • You're leaking errorSave which you should initialize as nil anyway.
  • You should never ever call dealloc yourself, use release instead. But don't release saveString because it's already autoreleased (see above), you're over-releasing it here which will cause a crash when the autorelease pool is drained.


Ok, there's a couple problems with your code:


Method signature has a trailing semi-colon

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

EDIT: Per @omz and @Rudy Velthuis, a trailing semi-colon on an implementation method signature is allowed by Objective-C. So you can ignore this 'problem'.


You should use the class instance for getting handle to save panel

NSSavePanel * savePanel = [NSSavePanel savePanel];

You should check the result of running the save panel modally

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

*You are creating an instance of NSString * and leaking it, totally unnecessary*

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

Once you correct the problems outlined above, you will want to remove the two dealloc lines, since the objects will now be autoreleased. Note that you normally want to call release in your code anyway, not dealloc.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜