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 (Cocoa-dev@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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to