OK. I'll be looking for the answer, and may find it myself. I have a nasty habit of answering my own questions.
In any case, I have an app that is designed to be "skinned" fairly easily. As part of that, I have sequestered methods in a static class that is specific to variants. These static methods feed the main app images, colors and settings specific to the variant. The .h file is common to the main app, but the .m file is specific to the variant.
I like to use the ability to send an image as a background (which is automagically tiled), so the interface file specifies the routine as returning a UIColor, like so:
+ (UIColor *)meetingDetailBackgroundColor;
But the implementation file loads an image file, and returns that, like so:
+ (UIColor *)meetingDetailBackgroundColor
{
return [UIColor colorWithPatternImage:[UIImage imageNamed:@"DarkWeave.png"]];
}
Which is used in context, like so:
[[self view] setBackgroundColor:[BMLTVariantDefs meetingDetailBackgroundColor]];
NOTE: Edited to restore the original simple code I used.
Now, the issue is that I sometimes (not always) get a leak.
I'm sure that I'm doing something hinky here. I'm just not sure what.
Any ideas?
BTW: This is an ARC program, running on IOS 5. I'm new to ARC, but I think this is the way I'm supposed to do it.
UIColor colorWithPatternImage
is buggy, do not use it. My experience is that it tends to greatly cripple performance on the device but not in the simulator. Anything like scrolling or animation on top of it tends to get slow. I'm not sure whether this really qualifies as a leak, I'm not seeing App being killed because RAM ran out. But if you profile the app, you will see that the app runs much slower with UIColor colorWithPatternImage
enabled and drawing something.
Eventually I created a subclass of UIView
, and did something like this:
- (void)drawRect:(CGRect)rect
{
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextSetBlendMode(c, kCGBlendModeCopy);
CGContextDrawTiledImage(c, CGRectMake(0, 0, bkgnd.size.width, bkgnd.size.height), bkgnd.CGImage);
}
This will tile the image. I then either use self.tableView.backgroundView
or [self.view insertSubview:bkgnd atIndex:0]
to make it a background. It runs much faster on the device, and causes zero memory leaks.
The best way to initilise your shared colour is like this:
+ (UIColor *)color
{
static UIColor *color;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
color = [[UIColor alloc] init...];
});
return color;
}
It is thread safe and only initialises the colour once. That way there is no way that you can leak the colour.
OK. I addressed this, but I did not fix it.
I punted.
It is, indeed, Instruments making wild guesses. There was nothing wrong with the way I specified the color (however, I liked one of the suggestions here, and redid my color spec that way).
It seems to be a very small leak, buried somewhere deep in the bowels (and I mean that literally) of MapKit. There seems to be absolutely nothing that I can do to resolve it.
After several hours of brick wall/neocortex interaction, I just gave up, and made the screen controller object reusable. I simply keep it hanging around, and change the contents to suit the meeting being inspected.
That puts off the leak until the app closes.
I am such a wimp.
Thanks.