viewDidUnload is no longer called in iOS6, so as a workaround for an app that does some necessary things in viewDidUnload I have done this:

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];


    // only want to do this on iOS 6
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0) {
        //  Don't want to rehydrate the view if it's already unloaded
        BOOL isLoaded = [self isViewLoaded];

        //  We check the window property to make sure that the view is not visible
        if (isLoaded && self.view.window == nil) {

            //  Give a chance to implementors to get model data from their views
            [self performSelectorOnMainThread:@selector(viewWillUnload)
                                   withObject:nil
                                waitUntilDone:YES];

            //  Detach it from its parent (in cases of view controller containment)
            [self.view removeFromSuperview];
            self.view = nil;    //  Clear out the view.  Goodbye!

            //  The view is now unloaded...now call viewDidUnload
            [self performSelectorOnMainThread:@selector(viewDidUnload)
                                   withObject:nil
                                waitUntilDone:YES];
        }
    }
}

Is there any precedent for Apple rejecting something like this? Due to time constraints I can't risk them rejecting anything.

有帮助吗?

解决方案

There's no reason they would reject this. By deprecating the method, -[UIView viewDidUnload] simply becomes like any other method. You can treat it as if it never existed on UIView in the first place and you just happened to create a method called -viewDidUnload.

It would be a problem if -viewDidUnload still existed internally (which it might) and you attempted to call Apple's (now private) implementation instead of your own but I highly doubt Apple would do this. Just remember in your -viewDidUnload to remember to ask if the super class implements the method before attempting to call it on super if that's what you're currently doing, using:

if ([[self superclass] instancesRespondToSelector:@selector(viewDidUnload)]) {
    [super viewDidUnload];
}

If you really wanted to be safe you could always move your code to a different method. Inside viewDidUnload just call your new method for iOS 5 devices and in -didReceiveMemoryWarning call your new method if you're on iOS 6.

I'm not going to comment in length on the logic in your didReceiveMemoryWarning since that wasn't in the question but I will say that you should be very careful about the state you're putting the controller in (make sure those if statements cover all of your bases!) And of course, you cannot expect your view controller and its views to be in the same state when viewDidUnload is called by you as when it was called by UIKit in iOS 5.

其他提示

There's no reason why Apple would reject it, but they removed it for a reason.

Calling it manually is just asking for problems. I strongly recommend to get the application logic right and do it the "correct" way.

Edit: After looking over that code again, I have serious doubts about your implementation. The whole construct with calling selectors (we should already be on the main thread!) and removing from superview (which just steals the view from it's owner without telling it) just cannot be correct. This is the type of code that you really want to eliminate from your code base.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top