PDA

View Full Version : Need help with Xcode alert sheet




NexesDev
May 14, 2008, 11:53 PM
When I run the program everything works and the alert sheet comes up, but when I click the "OK" button to delete the folder, it does nothing, just sits there. What am I doing wrong? Any suggestions would be a great help.

Here is the alert sheet part of the implementation file...

-(IBAction)deleteFolder:(NSButton *)sender
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

NSString *title = @"Are you sure you want to delete your created folder?";
NSString *defaultButton = @"YES";
NSString *alternateButton = @"NO";
NSString *msg = @"your friendly reminder";

NSBeginAlertSheet(title,
defaultButton,
alternateButton,
nil,
window,
self,
@selector(sheetDidEnd:returncCode:contextInfo:),
nil,
nil,
msg);

[pool release];
}

-(void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
{

if (returnCode == NSAlertDefaultReturn)
{
NSFileManager *nsf = [NSFileManager defaultManager];

[nsf removeFileAtPath:@"/Users/joeb/Desktop/NewFolderMan/" handler:nil];
}
}



Streamer
May 15, 2008, 10:10 AM
I'm still heavily learning this stuff, but I had a real headache as I experimented with that at the weekend. For me the problem was passing the "window" in the call, xcode kept warning me it would probably get ignored.

I tried "self window","window" etc but all no joy. I think in the end "self delegate" did it. I'm not near my MBP at the moment so I may have misquoted that, but it sounds like you and I are at the same place in learning Cocoa :)

Once I sorted that, it still didn't play ball, but I found using breakpoints my SheetDidEnd was getting called, but I had screwed up the return code check!

Hope the above may help a little!

Krevnik
May 15, 2008, 12:18 PM
When I run the program everything works and the alert sheet comes up, but when I click the "OK" button to delete the folder, it does nothing, just sits there. What am I doing wrong? Any suggestions would be a great help.

Here is the alert sheet part of the implementation file...

* snip for great justice *


Please use the code BB tag when posting code, it makes it easier to read. :)

Have you tried placing a breakpoint on the 'if' line in your didEnd method, and see if you hit it?

iSee
May 15, 2008, 01:46 PM
I'm hardly an expert, but I have run alert sheets like this successfully.
It looks fine.

Try getting rid of the autorelease pool stuff. You don't need it and there's a chance it is freeing stuff that NSBeginAlertSheet allocated too early.

Krevnik
May 15, 2008, 02:59 PM
I'm hardly an expert, but I have run alert sheets like this successfully.
It looks fine.

Try getting rid of the autorelease pool stuff. You don't need it and there's a chance it is freeing stuff that NSBeginAlertSheet allocated too early.

I would get rid of the autorelease pool as well, but the odds of it releasing objects 'too early' are pretty much zero.

The autorelease pool is /meant/ to operate correctly like that. Objects only get added if they are autoreleased (standard releases don't interact with the pool), and they only get released from the pool if their refcount hits zero as the pool drains.

An object being created in an autoreleased state is passed around by reference along the stack, and code should be placing a retain on it if they intend to keep a reference around. If not, the safe assumption is that it is safe to release.

If he did manage to trip across a bug with NSBeginAlertSheet() he would see exceptions getting thrown in his output log.

NexesDev
May 16, 2008, 01:28 AM
Thanks for the help guys, i tried the idea of getting rid of the NSAutoReleasePool and it didn't work. However i finally got the alert sheet to work but i had to change it to this. My question now is, the new code seems like its less "sophisticated", is it a problem doing it like this? I had to use the NSRunAlertPanel instead of the NSBeginAlertSheet.

-(IBAction)deleteFolder:(NSButton *)sender
{

NSString *title = @"Are you sure you want to delete your created folder?";
NSString *defaultButton = @"YES";
NSString *alternateButton = @"NO";
NSString *msg = @"your friendly reminder";
NSInteger x;

x = NSRunAlertPanel (title,
msg,
defaultButton,
alternateButton,
nil);

if (x == NSAlertDefaultReturn)
{
NSFileManager *nsf;
nsf = [NSFileManager defaultManager];

[nsf removeFileAtPath:@"/Users/joeb/Desktop/NewFolderMan" handler:nil];
}


}

caveman_uk
May 16, 2008, 09:31 AM
That's how I would do it - although I'd make it less verbose

-(IBAction)deleteFolder:(NSButton *)sender
{

NSInteger x = NSRunAlertPanel (NSLocalizedString(@"Are you sure you want to delete your created folder?",nil),
NSLocalizedString(@"your friendly reminder", nil),
NSLocalizedString(@"Yes",nil),
NSLocalizedString(@"No",nil),
nil);

if (x == NSAlertDefaultReturn)
{
NSFileManager *nsf= [NSFileManager defaultManager];

[nsf removeFileAtPath:@"/Users/joeb/Desktop/NewFolderMan" handler:nil];
}


}

iSee
May 16, 2008, 10:25 AM
So much for my NSAutoReleasePool idea!

It's a moot point, but it bothers me that you had to just avoid NSBeginAlertSheet() altogether. I'm in the process of learning Cocoa, and I guess what bothers me is that I thought I understood NSBeginAlertSheet(). But I can't see what the problem was with your code. So I might *not* understand NSBeginAlertSheet() fully after all.

Oh well, I'm glad you're up and going :)

caveman_uk
May 16, 2008, 04:00 PM
Unless it's a typo this could be the problem in the OP's code


@selector(sheetDidEnd:returncCode:contextInfo:),


Note the extra 'c' in the returnCode. Maybe the method just never got called?

NexesDev
May 16, 2008, 04:37 PM
Thank you caveman_uk, what you suggested works perfectly. now im just confused on why. When i look up the NSBeginAlertSheet in the Xcode documentation, it never says "returncCode" just "returnCode". Am I looking in the wrong place? Any way thanks you guys for your help!!!

iSee
May 16, 2008, 05:58 PM
Ah Ha! Nice catch caveman.

sheetDidEnd:returncCode:contextInfo:

and

sheetDidEnd:returnCode:contextInfo:

are two different methods

That explains it: NexesDev, you told NSRunAlertPanel to send a message called "sheetDidEnd:returncCode:contextInfo:" to self. But it doesn't have a method called that. It has a method with a similar name; close but no cigar.

It's worth noting that you could have called the method anything, as long as you are consistent (and specify the correct parameters). You could specify @selector(pepperoni:pizza:pie:) in the call to NSRunAlertPanel() as long as you had a method-(void)pepperoni:(NSWindow *)sheet pizza:(int)returnCode pie:(void *)contextInfo { ... }