iOS 7.1 removeFromSuperview crash

incmiko picture incmiko · Mar 11, 2014 · Viewed 8.8k times · Source

My app didn't have any crash until iOS 7.1 came out. Now on any removeFromSuperview method, crash. For example: I got view controllers, and when I want to remove a view controller, I remove all of its subviews, and then remove from the stack (stack: I'm storing view controllers in this, for load new contents, and load previous contents):

    for (UIView *subView in [contentVc subviews])
         [subView removeFromSuperview];

And I got

-[CALayer retain]: message sent to deallocated instance

message

[actual removeFromParentViewController];

is a good way to remove it? And will it release the whole view controller and its subviews? Because instead of removeFromSuperview, my app doesn't crash. I don't understand what have been changed in iOS 7.1.

And how can I remove all subviews in a viewController without removeFromSuperview, and without remove my ViewController (if I just want to add new subviews, and remove the currently content)?

UPDATE:

sometimes crash for:

[myactualviewcontroller.view removeFromSuperview];

-[CALayer retain]: message sent to deallocated instance

Why???

and sometimes if I try to remove the main subview from the view controller view, its got the same crash:

[mainView removeFromSuperview] ( mainView is a single UIView, added to the vc.view )

UPDATE2: (well detailed)

so, I've got a container view. I'm adding a UIViewController.view to this container. And I'm adding a view as a subview to UIViewController.view. This view is not a local uiview, I mean, its declared as implementation{ UIView* mainView } .When my UIViewController will be deallocate, in its - (void) dealloc { [mainView removeFromSuperview]; [mainView release] [super dealloc];} At the mainView removeFromSuperview my app crash.

Answer

Aaron Golden picture Aaron Golden · Mar 20, 2014

It's usually not a good idea to modify an array while you're fast enumerating it. You appear to be using fast enumeration on a a view's array of subviews, and to be modifying that array at the same time (by removing subviews as you go). You could try something like this:

NSArray *subviewsCopy = [[contentVc subviews] copy];
for (UIView *subview in subviewsCopy) {
    [subview removeFromSuperview];
}

However, as some others have mentioned, it's a little odd that you need to go to the trouble of removing these subviews manually. Under normal circumstances a view controller's view (and the view hierarchy under it) will be cleaned up automatically when the view controller itself is deallocated.

There are also some good tools available that can help you track down the source of the issue. In particular, you should profile your app (in Xcode, under the Product menu) and choose the Zombies tool when Instruments prompts you. With Zombies you can see the retain/release history of an object that was messaged after it was deallocated.

If you're attempting this manual cleanup of the view hierarchy because you suspect that your views will be leaked otherwise, I suggest that you also try the Leaks tool in Instruments and verify that when this code is disabled the relevant views are actually leaked.