I have a few, full screen, UIColor PatternImages (in scrollViews) in my iPad app and am experiencing some memory problems (surprise?)
When I started having memory issues, I implemented lazy loading in my scrollviews.
When the problems continued, I moved away from factory methods
(like [UIColor colorWithPatternImage:...])
to “alloc”ed methods
(like [[UIColor alloc]initWithPatternImage:...]),
so I could respond to memory warnings by releasing pages.
However, whenever I release my UIColor PatternImages, I get an “EXC_BAD_ACCESS” error.
At first I thought this might be caused by my [UIImage imageNamed:...] pattern images, so I switched to [[UIImage alloc]initWithContentsOfFile:...] images, but this didn’t help. Just now I set NSZombiesEnabled and it tells me that the problem is:
-[UICGColor release]: message sent to deallocated instance 0x187b50
With the backtrace:
#0 0x35823910 in ___forwarding___ ()
#1 0x35823860 in __forwarding_prep_0___ ()
#2 0x357e53c8 in CFRelease ()
#3 0x357e48de in _CFAutoreleasePoolPop ()
#4 0x3116532c in NSPopAutoreleasePool ()
#5 0x341a7508 in _wrapRunLoopWithAutoreleasePoolHandler ()
#6 0x3580ac58 in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()
#7 0x3580aacc in __CFRunLoopDoObservers ()
#8 0x358020ca in __CFRunLoopRun ()
#9 0x35801c86 in CFRunLoopRunSpecific ()
#10 0x35801b8e in CFRunLoopRunInMode ()
#11 0x320c84aa in GSEventRunModal ()
#12 0x320c8556 in GSEventRun ()
#13 0x341dc328 in -[UIApplication _run] ()
#14 0x341d9e92 in UIApplicationMain ()
#15 0x00002e5e in main (argc=1, argv=0x2fdff610) at...
I don’t have any UICGColor objects either, so I’m thinking that somehow my “alloc”ed UIColors have underlying UICGColor autorelease objects…? Any ideas/insight?
OK, I have worked something out, thanks in part to the (poorly tagged and titled) SO question/answers here. What I needed to do was read-up about
UIView.backgroundColor. In my docs it says@property(nonatomic, copy) UIColor *backgroundColor. The “copy” here tells me that when I say something like:The
myUIView.backgroundColoris actually a different object to the[[UIColor alloc]initWithPatternImage:myUIImage]. This separatemyUIView.backgroundColoris, in fact, autoreleased, so when I go[myUIView.backgroundColor release];I am actually shooting myself in the foot. What I need to do is:(and of course, around that, I’m also allocing and releasing
myUIImage). Now to release my scrollView patternImage, I can just do something likecurrentPage.backgroundColor=nil;(like @BuildSucceeded) orcurrentPage.backgroundColor=[UIColor clearColor];(not sure if there is a practical difference). I guess internally, both of these causecurrentPagetoautoreleasethe oldbackgroundColor. Since making these changes, I haven’t been able to get my app to crash.I need to say this: I don’t think C++ does it quite right, but C# and Java both manage quite nicely without any of this complicated release, autorelease, @property business. Of course, if someone wanted to implement an analogous (to Objective-C) pointer management system in Java or C# they could, but of course no one wants this because it would be pretty useless. Pleeeease Apple, migrate away from Objective-C!