Here are my code snippets:
Using Control drag from the xib to the Document.h I added
@property (weak) IBOutlet NSMatrix *matrix;
and manually typed in
@interface NSMatrix (Draw)
-(void)drawRect:(NSRect)dirtyRect;
@end
In Document.m I added
@implementation NSMatrix (Draw)
-(void)drawRect:(NSRect)dirtyRect
{
// some drawing stuff
}
@end
This allows me to add whatever calls to drawRect I wish from
within methods in Document.m
What do you think of this approach? Is there a more elegant way?
TIA and respect….
Peter
_______________________________________________
Cocoa-dev mailing list (Coco...@lists.apple.com)
Please 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:
https://lists.apple.com/mailman/options/cocoa-dev/cocoa-dev-garchive-98506%40googlegroups.com
This email sent to cocoa-dev-ga...@googlegroups.com
The problem with this approach is that you've replaced the drawRect:
for every NSMatrix instance, everywhere, in your app. If some Cocoa
control is using NSMatrix, suddenly it's using your drawRect:. If you
decide to use NSMatrix somewhere else, it too is using this drawRect:.
I wouldn't trust this to be very stable. And I don't see how
subclassing is much more work than this.
> I wouldn't trust this to be very stable. And I don't see how
> subclassing is much more work than this.
Agreed. Absolutely do not do this — using categories to change the behavior of existing classes is quite dangerous.
Also, why do you need to override -drawRect: for an NSMatrix anyway? Generally it's the cells you want to customize the drawing of, not the matrix that holds them.
—Jens
> In a Document app I have an NSMatrix. I only need to override drawRect.
> Rather than using a sub-class, which seems overkill to me,
> I decided to try a Category instead.
Categories don't override, they replace. As has already been noted , this means every NSMatrix instance in your app now uses your drawRect:. But it also means you can't have two instances of NSMatrix that had different drawing and you can no longer access the original implementation.
--
David Duncan
David:
I had carefully read the Categories and Extensions page in OBJ-C Programming Language.
And, based on the first paragraph, assumed I could add functionality to drawRect for my particular case.
Stephen:
In my app there is only the one NSMatrix instance but it's true I've no idea what other Cocoa classes
will call my drawRect. Although I do [super drawRect] after my own drawing.
Jens:
I am aware of the difference between the matrix and it's cells.
For the matrix I want to do some special drawing of the background beyond filling, including stroking the bounds.
I also need to deal with placing the cells differently than the default. I want to inset them differently.
But that's the next thing to play with.
Anyway guys thanks for your kindness and contribution to my education.
I will return to the mountain to meditate some more.
respect….
Peter
You can use categories to add functionality to existing *classes*, but
you shouldn't use it to override or replace *methods* that are already
implemented in those classes.
Per
> In my app there is only the one NSMatrix instance
There's no way to tell, really. For all I know, the Open or Save panels might use NSMatrix. Or the Find panel or the font panel. Heck, I believe in the old days of OpenStep, menus were implemented as NSMatrixes of menu item cells.
Also, if you ever need to add another different NSMatrix somewhere else in your app, you're now SOL because you'll now have to rip out the category method and re-implement your code the right way using subclassing.
> Although I do [super drawRect] after my own drawing.
That won't call the old NSMatrix drawRect, it'll call the drawRect of the superclass of NSMatrix, which is NSControl. You've effectively deleted the original NSMatrix drawRect implementation, so it's impossible to call it without some tricky gymnastics. One more time: a category doesn't override a method, it replaces it. It literally edits the class's method table to replace the old function pointer with the new one. The only way to properly override a method, in the OOP sense, is to make a subclass.
—Jens
Thanks again.
Peter
_______________________________________________