[CALayer retain]: message sent to deallocated inst

2019-04-12 07:25发布

问题:

In my app when I am switching views, after about the 4th time I switch views I get a crash that says:

*** -[CALayer retain]: message sent to deallocated instance 0x6c4ba0

I have NSZombieEnabled in Xcode and it points me to this line whenever it switches views:

[self.view removeFromSuperview];

Also if I do a backtrace of the (gdb) it gives me this:

#0  0x37dd68a0 in ___forwarding___ ()
#1  0x37d31680 in __forwarding_prep_0___ ()
#2  0x37d1d026 in CFRetain ()
#3  0x37d26bb2 in +[__NSArrayI __new::] ()
#4  0x37d26acc in -[__NSPlaceholderArray initWithObjects:count:] ()
#5  0x3518e680 in -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:] ()
#6  0x3518e7a4 in -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:] ()
#7  0x3534c40c in __UIViewWillBeRemovedFromSuperview ()
#8  0x3518dad0 in -[UIView(Hierarchy) removeFromSuperview] ()
#9  0x000368a6 in __block_global_1 (.block_descriptor=<value temporarily unavailable, due to optimizations>, finished=1 '\001') at /Users/bobsComputer/Desktop/Projects/NewApp/MyApp/MyApp3/MyApp3ViewController.mm:135
#10 0x351a70be in -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] ()
#11 0x351a181a in -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] ()
#12 0x351a6fb8 in -[UIViewAnimationState animationDidStop:finished:] ()
#13 0x3354fba6 in CA::Layer::run_animation_callbacks ()
#14 0x37a91f7a in _dispatch_main_queue_callback_4CF$VARIANT$mp ()
#15 0x37da72dc in __CFRunLoopRun ()
#16 0x37d2a4dc in CFRunLoopRunSpecific ()
#17 0x37d2a3a4 in CFRunLoopRunInMode ()
#18 0x378a8fcc in GSEventRunModal ()
#19 0x351ba742 in UIApplicationMain ()

Also this how I switch views, I have a main view controller. I then use a ParentView and protocols to call these methods from my other views controllers. I then use custom UIView animations to switch views.

Does anyone have any ideas why this is crashing?

Thanks!

回答1:

-[UIView addSubview:] causes the subview to be retained, and -[UIView removeFromSuperview] causes the view to be released. This is direct from Apple's UIView documentation. At that point, one of your objects needs to retain the CALayer or it will be deallocated.

I assumed that the CALayer was created by you directly. All UIViews are associated with CALayers; the CALayer is what a UIView draws into, and then its CALayer is composited onto the screen. If you're not working with CALayers directly, this is a symptom of another problem.

The core problem you're describing is an overrelease. It's possible you're not retaining a UIView when you should. I suggest you run the Xcode analyzer (in Xcode 4, choose the Product > Analyze) menu item and see what gets reported. Pay special attention to all of the memory management errors it reports.



回答2:

I had the same problem. I was not using Interface Builder for my views. The cause was that a subview of the view that was causing the crash was being released twice (but not crashing upon the second release weirdly enough). So I would suggest you go into the view's initWithFrame method, or wherever you are adding your subviews to it and look at every release carefully. I usually do not implement the dealloc method since I am sending an autorelease message to every subview before I add it to the parent view. In this way i have less places to look at and I m sure that everything will be released once the parent view is discarded. Hope that helps...