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 anNSMutableString
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 fromabsoluteString
, causing the original string to leak. NSString
responds to neitherdeleteCharactersInRange:
nor toappendString
(those are methods ofNSMutableString
).- You're leaking
errorSave
which you should initialize asnil
anyway. - You should never ever call
dealloc
yourself, userelease
instead. But don't releasesaveString
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.
精彩评论