Snowman
Snowman

Reputation: 32061

Why does using a #define UIColor as CGColorRef cause crash?

I have a UIColor defined like this:

#define kCircleInnerShadowColor [UIColor colorWithWhite:.78 alpha:1.0]

Then I use it like this:

CGColorRef shadowColorRef = kCircleInnerShadowColor.CGColor;
CGContextSetShadowWithColor(cxt, size, 0, shadowColorRef);

However, that causes a BAD_ACCESS crash. If I instead do

CGContextSetShadowWithColor(cxt, size, 0, kCircleInnerShadowColor.CGColor);

I don't get a crash, and it works fine. What is the reason for this?

Upvotes: 0

Views: 1242

Answers (1)

daniel.gindi
daniel.gindi

Reputation: 3496

The reason it crashes, is because of scope issues. What you are doing is:

  1. Create a new UIColor object
  2. Retrieve its CGColor pointer
  3. Put that pointer into a new variable
  4. Release the UIColor object (The next line...)
  5. Use the CGColor pointer, which points to bad data already

When you do it in the "one line version", what you do is:

  1. Create a new UIColor object
  2. Retrieve its CGColor pointer
  3. Use the CGColor pointer in a function
  4. Release the UIColor object (The next line...)

So because you create the object in the same line where you use it, the compiler automatically keeps the object until the function call returns and proceeds to the next line. Only then it releases the object.

But when you set the CGColor to a variable, what happens is that the compilers sees that the object is not gonna be used anywhere, and sends a release. But the CGColor is not an NSObject and the compiler do not send a "retain" to the CGColor.

If you need the CGColor in a variable, You may want to use CGColorRetain.

CGColorRef shadowColorRef = CGColorRetain(kCircleInnerShadowColor.CGColor);

And then when you are finished with it, CGColorRelease

Upvotes: 3

Related Questions