Mysterious NSTextFieldCell deallocating
Mysterious NSTextFieldCell deallocating
- Subject: Mysterious NSTextFieldCell deallocating
- From: David Schmitt <email@hidden>
- Date: Thu, 18 Sep 2003 12:11:46 -0400
I'm trying to subclass NSTextFieldCell to draw a small filled bezier path in the right hand side of the cell and then respond to clicks on the graphic. I created a small test app, and am able to successfully draw the path. But when I click on the cell, the app crashes. Here's part of the crash log:
Exception: EXC_BAD_ACCESS (0x0001)
Codes: KERN_INVALID_ADDRESS (0x0001) at 0x18000000
Thread 0 Crashed:
#0 0x9068ba54 in objc_msgSend
#1 0x932376f8 in -[NSAffineTransform transformBezierPath:]
#2 0x00004750 in -[DASComboBox drawInteriorWithFrame:inView:] (DASComboBox.m:61)
#3 0x930a0758 in -[NSTableView drawRow:clipRect:]
#4 0x930cede8 in -[NSTableView drawRect:]
#5 0x930809ec in -[NSView _drawRect:clip:]
For efficiency's sake, I create my bezier path in my -init code, and then apply a transform in -drawInteriorWithFrame: inView:
Digging into the app, I have discovered that for some reason my subclasses' -dealloc is being called, and I cannot figure out why. Here's the traceback to my dealloc call. Clearly the table view is releasing the cell -- why?
If I do not create the bezier path in -init and instead create it every time in -drawInteriorWIthFrame: inView: then the app does not crash, yet -dealloc still gets called every time *and* init is only called once. How can that be?
#0 0x000048e0 in -[DASComboBox dealloc] at DASComboBox.m:83
#1 0x930a9db8 in -[NSCell release]
#2 0x93122bf8 in -[NSTableView mouseDown:]
#3 0x930c102c in -[NSWindow sendEvent:]
#4 0x930a8e20 in -[NSApplication sendEvent:]
#5 0x930b1dac in -[NSApplication run]
#6 0x9315fc58 in NSApplicationMain
#7 0x0000414c in main at main.m:13
Here's the code. I have a nib file that contains an NSTableView with two columns. For column 1, I set my subclassed NSTextFieldCell as the data cell:
@interface Controller : NSObject {
IBOutlet NSTableView *myTable;
}
@end
@implementation Controller
-(void)awakeFromNib
{
[[myTable tableColumnWithIdentifier:@"one"] setDataCell:[[DASComboBox alloc] init]];
}
- (int)numberOfRowsInTableView:(NSTableView *)aTableView
{
return 10;
}
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
{
if ([[aTableColumn identifier] isEqualToString:@"two"])
return [NSNumber numberWithInt:rowIndex];
else
return @"Loooooooooooooong string";
}
@end
@interface DASComboBox : NSTextFieldCell {
NSBezierPath *_trianglePath;
}
@end
#define triangleSideLength 9.0
#define triangleHeight sqrt(0.75 * pow(triangleSideLength,2.0))
@implementation DASComboBox
-(id)init
{
if (self = [super init])
{
_trianglePath = [[NSBezierPath alloc] init];
NSPoint triangleStartPoint = NSMakePoint(0,0);
//float triangleSideLength = 9.0;
[_trianglePath moveToPoint:triangleStartPoint];
[_trianglePath lineToPoint:NSMakePoint(triangleStartPoint.x+ triangleSideLength,
triangleStartPoint.y)];
[_trianglePath lineToPoint:NSMakePoint(triangleStartPoint.x+(triangleSideLength/2.0),
triangleStartPoint.y+triangleHeight)];
[_trianglePath closePath];
NSLog(@"Init called.");
}
return self;
}
- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
NSRect textRect, imageDrawRect;
NSPoint triangleTranslatePoint;
NSAffineTransform *transform = [NSAffineTransform transform];
NSBezierPath *myBezierPath;
NSDivideRect(cellFrame, &textRect, &imageDrawRect, cellFrame.size.width-triangleSideLength, NSMinXEdge);
triangleTranslatePoint = NSMakePoint(imageDrawRect.origin.x, imageDrawRect.origin.y + (imageDrawRect.size.height - triangleHeight)/2.0);
textRect.size.width = textRect.size.width - 2.0;
[transform translateXBy:triangleTranslatePoint.x yBy:triangleTranslatePoint.y];
[super drawInteriorWithFrame:textRect inView:controlView];
[controlView lockFocus];
if ([self isHighlighted])
[[NSColor whiteColor] set];
else
[[NSColor grayColor] set];
myBezierPath = [transform transformBezierPath:_trianglePath];
[myBezierPath fill];
[controlView unlockFocus];
}
-(void)calcDrawInfo:(NSRect)aRect
{
[super calcDrawInfo:aRect];
NSLog(@"calcDrawInfo: called.");
}
- (BOOL)startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView
{
NSLog(@"startTrackingAt: called");
return [super startTrackingAt:startPoint inView:controlView];
}
-(void)dealloc
{
NSLog(@"Dealloc called.");
[_trianglePath release];
[super dealloc];
}
@end
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.