Xeijp Xeijp - 1 year ago 59
Objective-C Question

Is it possible draw CGContext in blocks?

On IOS, I have a NSArray stores

that drawing something on the UIView, for example :

^(CGContextRef ctx) {
// drawing rectangle
CGRect rect = CGRectMake(0, 0, 300, 300);
CGContextSetRGBFillColor(ctx, 1, 0, 0, 1);
CGContextFillRect(ctx, rect);
CGContextStrokeRect(ctx, rect);

There would be several blocks stored in the array, and I expect those block execute sequently when
got invoked, here's my

- (void)drawRect:(CGRect)rect {
// execute blocks
for(NSDictionary * task in drawTaskQueue)
DrawTaskBlock block = [task objectForKey:@"block"];
block(args, UIGraphicsGetCurrentContext());

But when I run the code, I'm sure the blocks got executed without any error, but nothing is showing up. Did I missed something ?

Answer Source

The problem with your code is that the block that you are passing expects a single parameter of type CGContextRef, while the calling code is passing two arguments - args and UIGraphicsGetCurrentContext().

Since Objective-C does not check the cast, your blocks end up running with a wrong graphic context, causing undefined behavior.

To fix this problem you need to make sure that the "signature" of the block matches the signature of the block type to which you cast it, i.e. DrawTaskBlock. The signature must include the proper type of the args parameter, even if none of your blocks is using it.