Re: Using NSAlert Sheets
Re: Using NSAlert Sheets
- Subject: Re: Using NSAlert Sheets
- From: Ryan Britton <email@hidden>
- Date: Wed, 20 Dec 2006 20:43:27 -0800
The main thread drains its autorelease pool at each iteration of the
application's run loop. It is in this pool that you're autoreleasing
your NSAlert instance. Sheets are such that they do NOT block the
run loop when up so your NSAlert instance is being freed before
you're really done with it.
NSAlert does not currently generate any retains on itself on creation
other than the one it gives you implicitly in its init method. As a
result, you must keep (and should anyway by Cocoa memory management
rules) that retain throughout the entire duration you need the
NSAlert instance. Though it may seem like you're done with it once
you pop up the sheet, you are not because the NSAlert instance is
referenced in the didEndSelector.
The pattern you should be following here is this:
- (void)aMethodThatGeneratesAnAlert
{
NSAlert *someAlert = [[NSAlert alloc] init];
//Set up someAlert
[someAlert beginSheetModalForWindow:someWindow modalDelegate:self
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
contextInfo:nil];
}
- (void)alertDidEnd:(NSAlert *)anAlert returnCode:(int)returnCode
contextInfo:(void *)contextInfo
{
[anAlert autorelease];
//Handle any other cleanup for the alert
}
On Dec 20, 2006, at 7:14 PM, Matt wrote:
I was trying to think this through conceptually. So, I create an
NSAlert object and call the -beginSheet... method on the object. I
played around with this code a bit more and ran across my confusion.
I would think that if I call the sheet and I need to wait for the
user's response, that my current call would be placed on the stack
and I would return to that later, after the user has closed the
alert and the -sheetDidEnd method has been finished. However, I
put a few NSLog() statements right after the initial call in the
calling method and those easily get printed before the user ever
does any interacting with the sheet itself.
Since I'm immediately returning from this calling method, my
NSAlert object is being released before the user could ever hope to
read and interact with the alert, therefore causing my issue.
So, just to clarify, how should I implement something like this? I
could retain the object as someone suggested, but I would need to
release it at the end of my calling method. If I release it there,
it will be released just like it originally was and I'm in the same
boat. (I can confirm this, already been messing with it). Should
I retain the object after I create it and release it in the -
sheetDidEnd method?
I've already looked through the documentation for the class and the
few other ways of calling alerts via functions, etc, but I was just
wondering if anyone wanted to share any personal experiences on the
subject. Surely this is a common task and there is a simple solution.
On Dec 20, 2006, at 8:29 PM, email@hidden wrote:
To expand on this, the alert is being released once the sheet
begins. You'll need to retain it through the duration of the sheet
and release only once the sheet is dismissed.
On Dec 20, 2006, at 1:00 PM, Michael Watson wrote:
Try not autoreleasing the alert object. Release it manually when
you're finished with it.
--
m-s
On 19 Dec, 2006, at 21:16, Matt wrote:
Quick question. I launch a sheet for an action using the code
below:
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
[alert addButtonWithTitle:@"Import Bookmarks"];
[alert addButtonWithTitle:@"Create New Bookmarks"];
[alert setMessageText:@"Your bookmarks are missing!"];
[alert setInformativeText:@"I can't find your bookmarks. If
you have a backup, use 'Import Bookmarks' to import your backup
copy."];
[alert setAlertStyle:NSCriticalAlertStyle];
// Call the alert sheet asking for migration
[alert beginSheetModalForWindow:mainWindow modalDelegate:self
didEndSelector:@selector
(BookmarksLoadAlertDidEnd:returnCode:contextInfo:)
contextInfo:nil];
The code seems to execute alright, except I get malloc() errors
when I run the code, and about 1/10th the time the app is prone to
crashing, presumably because of this. I don't see why there
should be a problem here, but am I missing something? The errors
I get are:
Viewer(2435,0xa000cfc0) malloc: *** Deallocation of a pointer not
malloced: 0x18d8c00; This could be a double free(), or free()
called with the middle of an allocated block; Try setting
environment variable MallocHelp to see tools to help debug
Viewer(2435,0xa000cfc0) malloc: *** error for object 0x1875800:
incorrect checksum for freed object - object was probably modified
after being freed, break at szone_error to debug
Viewer(2435,0xa000cfc0) malloc: *** set a breakpoint in
szone_error to debug
I'm going to try and figure out how to set MallocHelp and see what
that turns up as well. Just wondering, as right it's causing me
some problems.
Thanks
Matt
_______________________________________________
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden