Correct way to release a UIColor PatternImage
I have a few, full screen, UIColor PatternImages
(in scrollViews
) in my iPad app and am experiencing some memory problems (surprise?)
[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?
Me too had the same problem and this is how i optimized my code.
After some analysis in Instruments and debugging i found out that colorwith pattern will occupy 1.12 mb with a responsible library called ripl_create. For each screen with colorWithPattern will occupy the same 1.12 and so you will have multiples oj 1.12 mb allocated. This sucked my app.so i decided No colorWithPattern.
I guess you want to set image to the background of a view. What i would suggest is keep a ImageView and place the image to it...
Now Coming to imageView optimization
If you want the image to be used in many part of the app or the view that contains the image will be frequently visited then go for imagenamed.
imageNamed will cache the image and will not release it even if you nil it or release it.
On the other case where you wwant image to be released
In you viewWillAppear or viewDidLoad assign the image to imageview
NSString *fileLocation = [[NSBundle mainBundle] pathForResource:@"yourImage" ofType:@"png"];
imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfFile:fileLocation]];
inYour viewDidDisappear set nil to release the image
imageView.image=nil;
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:
myUIView.backgroundColor=[[UIColor alloc]initWithPatternImage:myUIImage];
The myUIView.backgroundColor
is actually a different object to the [[UIColor alloc]initWithPatternImage:myUIImage]
. This separate myUIView.backgroundColor
is, in fact, autoreleased, so when I go [myUIView.backgroundColor release];
I am actually shooting myself in the foot. What I need to do is:
UIColor* tmpColor=[[UIColor alloc]initWithPatternImage:myUIImage];
currentPage.backgroundColor=tmpColor;
[tmpColor release];
(and of course, around that, I'm also allocing and releasing myUIImage
). Now to release my scrollView patternImage, I can just do something like currentPage.backgroundColor=nil;
(like @BuildSucceeded) or currentPage.backgroundColor=[UIColor clearColor];
(not sure if there is a practical difference). I guess internally, both of these cause currentPage
to autorelease
the old backgroundColor
. 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!
精彩评论