Re: NSView out of memory problem
Re: NSView out of memory problem
- Subject: Re: NSView out of memory problem
- From: Graham Cox <email@hidden>
- Date: Wed, 2 Apr 2008 00:36:53 +1100
On 1 Apr 2008, at 11:40 pm, Leslie Smith wrote:
Hi:
I have a Cocoa application which draws a (very) large number of line
segments using the code below in a loop, in drawRect, in a subclass
of NSView.
p1 = [NSBezierPath bezierPath] ;
[p1 moveToPoint: linebottom] ;
[p1 lineToPoint: linetop] ;
[p1 stroke] ;
(These are the outputs from a neural network simulator.) I'm just
using one NSView: if I draw a set of outputs, and then (later) draw
another set of outputs (filling the rect with white in between), I
eventually run out of memory. Clearly, I need to free up something
but I really do not know what. (Well, I should probably create a new
NSView each time, but I'd like a quicker fix.)
I tried [p1 release] ; after the code above, but that simply made
the app crash.
I can't seem to find anywhere that tells me how to do this: it looks
as though once I have drawn something in an NSView, using
NSBezierPath, the memory used stays used. I'm sure I'm missing
something.
An observation: this is about as inefficient as you can get for
drawing a large number of lines.
Here's a few things I'd do:
1. do not construct the bezier path when you handle drawRect: - that
method is called to draw the output, not create it.
2. use a bezier object to collect the output from the neural simulator
when it runs. Keep the bezier object around by retaining it in an ivar
of your view class. You can create the bezier object as part of your
view's initWithFrame: method, if you like.
3. at the top of the loop, clear the bezier object using -
removeAllPoints.
4. within the loop, use moveTo/lineTo to collect your output.
5. in your view's drawRect:, just draw - set up the drawing parameters
(colours, line weight) and stroke the bezier path you made earlier. Do
not release it, or do anything else. You can erase the background to
white before stroking the path but note that you are drawing into the
view, not changing the bezier path content. (Think of your bezier
object as storing the graphical output from your simulator in a form
that can later be drawn directly into the view).
6. Certainly you will never be recreating views each time you draw,
that's simply wrong. Views typically stick around, and in this case, I
believe your bezier object should too.
7. If you rework your code to do it this way, not only will you not
run into memory problems, but you should see a dramatic boost in speed
too.
------
S.O.S.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden