Drawing a large number of lines (CGContextBeginPath) on an iPad
I'm trying to make an ipad application that draws alot, but I really mean alot of lines on stage (10.000+)
using this simple forloop, my ipad crashes after 40~60 seconds (without showing result)
for ( int i = 0; i < 10000; i++ )
{
int r_x = rand() % 750;
int r_y = rand() % 1000;
CGPoint pointpoint = CGPoint开发者_运维百科Make(r_x, r_y);
UIColor *st = [[GetColor alloc] getPixelColorAtLocation:pointpoint];
DrawLine *drawview = [[DrawLine alloc]initWithFrame:CGRectMake(r_x, r_y, 20, 20) selectedcolor:st];
[self.view addSubview:drawview];
[drawview release];
[DrawLine release];
[GetColor release];
}
and this is my "DrawLine" class:
- (id)initWithFrame:(CGRect)frame selectedcolor:colors{
if ((self = [super initWithFrame:frame])) {
selectedcolor_t = colors;
self.backgroundColor = [UIColor clearColor];
}
return self;
}
- (void)drawRect:(CGRect)frame{
CGContextRef c = UIGraphicsGetCurrentContext();
float* colors = CGColorGetComponents(selectedcolor_t.CGColor);
CGContextSetStrokeColor(c, colors);
CGContextBeginPath(c);
CGContextMoveToPoint(c, 0.0f, 0.0f);
CGContextAddLineToPoint(c, 20.0f, 20.0f);
CGContextStrokePath(c);
}
how can I solve this problem? How can I draw this much subviews without crashing the iOS?
thanks so much!! :)
Please reconsider what you are doing there:
- In line 4 of your loop, you
alloc
an instance ofGetColor
— which you never use again. Ask yourself: Does that make any sense from a design point of view? - In that same line, if you don't violate Cocoa's naming-conventions, you create a UIColor that is never released...
- Then in line 8 you release the class-object of
DrawLine
(ditto that for the next line and theGetColor
-class). This is terribly, horribly wrong!
Please visit the Memory Management Programming Guide at the iOS Dev-Center and read the first two sections (again)!
Besides that, re-evaluate your design:
- Should
GetColor
really be a class, so that you create instances? Wouldn't a simple helper-function for color interpolation make more sense in this context? - If it should be a class, why not create just one instance of it outside of the loop and simply query it repeatedly for the colors?
- Do you really need a subclass of UIView to draw a single straight, solid, single-colored line? If the lines need not be updated, you should (as Richard and nacho4d suggested) draw all of them in one object (e.g. by a custom UIView or by a delegate of CALayer implementing the
drawLayer:inContext:
method). If you need to update those lines later, you could simply (ab)use CALayer...
In the latter case, your problem then becomes:
- Calculate your random coordinates.
- Calculate your color.
- Create an opaque CALayer with
a) that color as its backgroundColor,
b) a width of 20 * sqrt(2),
c) a height of whatever-you-want-to-be-the-width-of-that-line,
d) your point as its origin and
e) arotation
of 45. - Add that layer as a sublayer to
self.view
's layer.
Cheers
Daniel
If your lines are static (not moving later, not animating, etc) , as they seem to be, you could also draw all the lines in a single drawRect: in one view without creating 1000 of CALayers. I can't tell if this is faster than drawing 1000 CALayers (because CoreAnimation is hardware accelerated and CoreGraphics is not) but it's surely lighter since all the lines will be flattened in a single bitmap. (which is the context of your view)
Just move your for loop inside your drawRect: and follow danyowde advices.( you just need one color object or a helper function but not to create a color each iteration)
Good luck, Hope it helps;)
精彩评论