subdigital/nsscreencast — pull request #1 by andrewsardone (2012-09-19 13:24:38+00:00)
Title: Fix ARM+ARC EXC_BAD_ACCESS in glossy gradient drawing

Within `drawGlossyGradient()`, the `shineStarColor` and `shineEndColor` `CGColorRefs` become bad pointers by the time they're passed into `drawLinearGradient()`. This is because the `UIColor` from which they were built had been released via ARC's “avoid the autorelease pool” optimization. In testing, this optimization only seems to manifest itself on iOS devices and not in the simulator.

For a thorough explanation of the issue, see the Big Nerd Ranch's blog post, [ARC Gotcha – Unexpectedly Short Lifetimes][1].

Now there are several ways to prevent this ARC optimization, all enumerated in the above blog post. The two most reasonable methods, IMHO, involve either an explicit `CGColorRetain`/`CGColorRelease` or holding onto the `UIColor` pointer and later accessing its `CGColor`. The latter approach (displayed in the patch below) was not used in this pull request despite it being the Big Nerd Ranch suggested resolution. Even though peppering your code with explicit memory management can be cumbersome, I found the overhead of understanding the *implicit* memory management of the `UIColor` and later `-[UIColor CGolor]` message send to be high and prone to a potential reintroduction of the bug via a naive refactoring.

Here is the diff for using the `UIColor` / `-[UIColor CGColor]` method:

```diff
diff --git a/032-core-graphics-gradients/FunWithGradients/FunWithGradients/DrawingHelpers.m b/032-core-graphics-gradients/FunWithGradients/FunWithGradients/DrawingHelpers.m
index bfffbb5..c1dfd03 100644
--- a/032-core-graphics-gradients/FunWithGradients/FunWithGradients/DrawingHelpers.m
+++ b/032-core-graphics-gradients/FunWithGradients/FunWithGradients/DrawingHelpers.m
@@ -38,13 +38,13 @@ void drawLinearGradient(CGContextRef context, CGColorRef color1, CGColorRef colo
void drawGlossyGradient(CGContextRef context, CGColorRef color1, CGColorRef color2, CGRect rect) {
drawLinearGradient(context, color1, color2, rect);

- CGColorRef shineStartColor = [[UIColor colorWithWhite:1.0 alpha:0.05] CGColor];
- CGColorRef shineEndColor = [[UIColor colorWithWhite:1.0 alpha:0.6] CGColor];
+ UIColor *shineStartColor = [UIColor colorWithWhite:1.0 alpha:0.05];
+ UIColor *shineEndColor = [UIColor colorWithWhite:1.0 alpha:0.6];

CGRect shineRect = CGRectMake(CGRectGetMinX(rect),
CGRectGetMinY(rect),
CGRectGetWidth(rect),
floorf(CGRectGetHeight(rect) / 2.0));

- drawLinearGradient(context, shineStartColor, shineEndColor, shineRect);
+ drawLinearGradient(context, shineStartColor.CGColor, shineEndColor.CGColor, shineRect);
}
\ No newline at end of file
--
```

[1]: http://weblog.bignerdranch.com/296-arc-gotcha-unexpectedly-short-lifetimes/