Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6980529
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T18:01:58+00:00 2026-05-27T18:01:58+00:00

I am trying to write a CGFunctionRef that will act as a shading function

  • 0

I am trying to write a CGFunctionRef that will act as a shading function for a CGShadingRef object in my project that uses ARC. I am trying to pass a NSMutableArray (filled with UIColors) into my CGFunctionRef callback.

Here is my init method

- (void)initInternal {  
    _colors = [[NSMutableArray alloc] init];

    // Creating the colors in this way ensures that the underlying color space is UIDeviceRGBColorSpace
    // and thus has 4 color components: red, green, blue, alpha
    [_colors addObject:[UIColor colorWithRed:1.0f green:0.0f blue:0.0f alpha:1.0f]]; // Red
    [_colors addObject:[UIColor colorWithRed:0.0f green:1.0f blue:0.0f alpha:1.0f]]; // Green
    [_colors addObject:[UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:1.0f]]; // Blue
    [_colors addObject:[UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:1.0f]]; // White
    [_colors addObject:[UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0f]]; // Black

    // Define the shading callbacks
    CGFunctionCallbacks callbacks;
    callbacks.version = 0;                      // Defaults to 0
    callbacks.evaluate = CGShadingCallback;     // This is our color selection function
    callbacks.releaseInfo = NULL;               // Not used

    // As input to our function we want 1 value in the range [0.0, 1.0].
    // This is our position within the 'gradient'.
    size_t domainDimension = 1;
    CGFloat domain[2] = {0.0f, 1.0f};

    // The output of our function is 4 values, each in the range [0.0, 1.0].
    // This is our selected color for the input position.
    // The 4 values are the red, green, blue and alpha components.
    size_t rangeDimension = 4;
    CGFloat range[8] = {0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f};

    // Create the shading function
    _shadingFunction = CGFunctionCreate(&_colors, domainDimension, domain, rangeDimension, range, &callbacks);   
}

Here is my callback method

static void CGShadingCallback(void* info, const float* inData, float* outData) {
    // Our colors
    NSMutableArray* colors = (__bridge_transfer NSMutableArray*)info;
    // Position within the gradient, ranging from 0.0 to 1.0
    CGFloat position = *inData;

    // Find the color that we want to used based on the current position;
    NSUInteger colorIndex = position * [colors count];

    // Account for the edge case where position == 1.0
    if (colorIndex >= [colors count])
        colorIndex = [colors count] - 1;

    // Get our desired color from the array
    UIColor* color = [colors objectAtIndex:colorIndex];

    // Copy the 4 color components (red, green, blue, alpha) to outData
    memcpy(outData, CGColorGetComponents(color.CGColor), 4 * sizeof(CGFloat));  
}

Here is my drawRect method

- (void)drawRect:(CGRect)rect {
    CGRect b = self.bounds;
    CGContextRef ctx = UIGraphicsGetCurrentContext();

    // Create a simple elliptic path
    CGContextAddEllipseInRect(ctx, b);
    // Set the current path as the clipping path
    CGContextClip(ctx);

    // Create our shading using the function that was defined earlier.
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    CGShadingRef shading = CGShadingCreateAxial(colorspace,
                                            CGPointMake(CGRectGetMinX(b), CGRectGetMidY(b)),
                                            CGPointMake(CGRectGetMaxX(b), CGRectGetMidY(b)),
                                            _shadingFunction,
                                            true,
                                            true);

    // Draw the shading
    CGContextDrawShading(ctx, shading);


    // Cleanup
    CGShadingRelease(shading);
    CGColorSpaceRelease(colorspace);
}

If I just use __bridge in my callback method, then is crashes on
NSMutableArray* colors = (__bridge NSMutableArray*)info;
with an EXC_BAD_ACCESS.

If I use __bridge_transfer, it crashes on
CGContextDrawShading(ctx, shading);
in the drawRect with an EXC_BAD_ACCESS.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T18:01:59+00:00Added an answer on May 27, 2026 at 6:01 pm

    You create a array and use that array as the context of a CGFunction.

    So that array needs to be retained when given to the function. You can do this with the __bridge_retained keyword:

    CGFunctionCallbacks callbacks;
    callbacks.version = 0;
    callbacks.evaluate = CGShadingCallback;
    callbacks.releaseInfo = myReleaseCallback;
    
    _shadingFunction = CGFunctionCreate((__bridge_retained void *)_colors, domainDimension, domain, rangeDimension, range, &callbacks);
    

    Then, you must not use in __bridge_transfer in the drawing callback. __bridge_transfer cast the value into a strong reference without retaining it (ownership is transferred). This is equivalent to releasing the array. As your callback may be invoked many times, this is not the right place to release the array.

    The array must be released when the function is destroyed. This is the purpose of the releaseInfo callback:

    static void myReleaseCallback(void *info) {
        CFRelease(info);
    }
    

    You can also do this with a __bridge_transfer cast but that’s is not very elegant:

    static void myReleaseCallback(void *info) {
        NSArray *array = (__bridge_transfer NSArray *)info;
        // now we need to do something with the array if we don't want a compiler warning
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm trying to write a regex function that will identify and replace a single
Trying to write a function that will write my structure array to a binary
Trying to write a PowerShell cmdlet that will mute the sound at start, unless
Trying to write a couple of functions that will encrypt or decrypt a file
im trying to write an app that will display a list off lines from
Trying to write function that numerize items of list and returns list of tuples
Trying to write a test for a helper method that uses acts_as_tree. Helper method
I am trying write a query that will display if the person has anyone
Trying to write a regular expression for java that will return true ONLY if
Trying to write a small function that updates a paragraph with an image's alt

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.