removeFromSuperview crash - please help
removeFromSuperview crash - please help
- Subject: removeFromSuperview crash - please help
- From: Keith Blount <email@hidden>
- Date: Sat, 6 Nov 2004 10:46:54 -0800 (PST)
Hello,
I have a custom NSView that creates subviews if you
double-click on it (I have been careful to ensure that
subviews can't overlap, though). A subview of this
view just contains a text view - it is basically a
note card (like a post-it). If the user clicks out of
the subview without typing anything into the note card
(so that the text view is empty), the note card
subview should be removed. I have also written a
method to clear all note card subviews.
Unfortunately, everything crashes whenever I call
removeFromSuperview, and I have absolutely no idea why
- I would be really grateful if someone could help me
out, because at the moment I seem to be faced with the
choice of either memory leaks or crashes, and it's
driving me crazy.
This is the hierarchy of the views:
Main view - an NSView subclass
NoteCard - created as subviews of the main view by
user double-clicking on main view
Text view subclass - a subclass of NSTextView that is
used inside a NoteCard
This is how I create a NoteCard on double-click:
// Double-click to create a note - main view method
- (void)mouseDown:(NSEvent *)event
{
int i = [event clickCount];
if (i == 2) // Double click
{
// Create a note
NSPoint p = [event locationInWindow];
NSRect frame;
frame.origin = [self convertPoint:p fromView:nil];
frame.origin.x = 0.0;
frame.origin.y -= [NoteCard headerHeight];
if (frame.origin.y < 0.0) frame.origin.y = 0.0; //
Don't create it above the top of the view
frame.size = NSMakeSize([self bounds].size.width,
40.0); // Should be as wide as the main view
// Now make sure that that does not intersect with
any other subviews
int i;
for (i=0; i < [[self subviews] count]; i++)
{
NSRect svFrame = [[[self subviews] objectAtIndex:i]
frame];
if ( NSIntersectsRect(frame,svFrame) )
{
NSBeep();
return;
}
}
NoteCard *noteCard = [[NoteCard alloc]
initWithFrame:frame];
[[self window] makeFirstResponder:[noteCard
textView]];
[self addSubview:noteCard];
[noteCard release];
}
}
(Note that if I don't include [noteCard release] I
don't get any crashes, but dealloc never gets called
on calling removeFromSuperview on the note card.)
This is how I remove the view if the user hasn't typed
anything in the text view - this code is contained in
a subclass of NSTextView, which is the only subview of
a NoteCard:
- (BOOL)resignFirstResponder
{
if ([[self string] length] == 0)
{
// If there is nothing in the text view, delete the
notecard:
[[self superview] removeFromSuperview];
return YES;
}
return [super resignFirstResponder];
}
Again, if I instead call [[[self superview] retain]
removeFromSuperview], I don't get a crash, but the
superview (a NoteCard) will never get released. At
first I thought this problem might be caused by
getting an object's child to try to remove that object
from its superview (hope that makes sense). But this
isn't the case as the program still crashes even if I
try to get the main NSView to remove its subviews (the
NoteCards), like this:
// Remove all the cards from the view
- (void)clear
{
id sv;
NSEnumerator *enumerator = [[self subviews]
objectEnumerator];
while (sv = [enumerator nextObject])
{
//[[sv retain] removeFromSuperview]; // Should not
need to have to retain here...
if ([sv textView] == [[sv window] firstResponder])
[[sv window] makeFirstResponder:nil];
[sv removeFromSuperview];
}
}
- This still crashes the program (unless I retain the
subview, which causes a memory leak).
Could anybody please tell me what I am doing wrong, or
what might be causing removeFromSuperview to crash?
>From everything I've tried and various NSLogs I've
done, it seems that if I retain the subview before
callling removeFromSuperview (or if I never release it
after adding it using addSubview: in the first place),
it will never be released. But if I release everything
in the proper place (ie. release the NoteCard after it
is added as a subview using addSubview:, relying on
its parent to retain it), then on calling
removeFromSuperview, release will be called too many
times and cause the app to crash.
If anybody can help, I would be really grateful.
Many thanks,
Keith
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden