Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 7 - Difference between viewDidLoad and viewDidAppear

People also ask

What is the difference between viewDidLoad and viewDidAppear?

The difference between viewDidAppear and viewDidLoad is that viewDidAppear is called every time you land on the screen while viewDidLoad is only called once which is when the app loads.

What is difference between viewWillAppear and viewDidAppear?

As the name suggests the viewWillAppear is called before the view is about to appear and viewDidAppear is called when view did appear.

Which is called first viewDidLoad or viewDidAppear?

viewDidLoad is called once when the controller is created and viewDidAppear is called each time the view, well, DID appear. So say you have a modal view that you present, when that view is dismissed, viewDidAppear will be called, and viewDidLoad will not be called.

What is viewDidLoad?

viewDidLoad is called when the ViewController has loaded its view hierarchy into memory. This is the point where you can perform your customized initialisation for your view controller. For instance, if your view controller has a UILabel and you want to set a custom text to it, this is the point where you do that.


Please Follow the below View Controller Life Cycle Every Time. You will be amazed with the coding and performance of your application in this manner.

enter image description here


I'm going to point you to Apple's docs because I think there is a need for some more explanation of the View Controller lifecycle than just answering your question as phrased.

https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/ViewLoadingandUnloading/ViewLoadingandUnloading.html

Ultimately, your view controller has a life cycle:

init - however you initialize your view controller

viewWillLoad/viewDidLoad - called when the view is constructed (via the first call to retrieve the view controller's UIView via it's view property - aka lazy loading)

viewWillAppear: - when the view is being prepared to appear either immediately (animated == NO) or view a transition (animated == YES)

viewDidAppear: - if the view appearance wasn't cancelled and the view controller's view fully appears

viewWillDisappear: - complements viewWillAppear:

viewDidDisappear: - complements viewDidAppear:

viewWillUnload/viewDidUnload - deprecated APIs when the view is unload due to memory constraints (don't worry about these anymore)

dealloc - the view controller itself is being deallocated

In the end though, I believe your issue may be that you are blocking the main thread with your array initialization. You should read up on asynchronous programming but in the meantime you could do something like this:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // other stuff

    __weak typeof(self) weakSelf = self;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        typeof(weakSelf) strongSelf = weakSelf;
        if (strongSelf) {
            [strongSelf initializeArraysSynchronously];
            dispatch_async(dispatch_get_main_queue(), ^{
                strongSelf.doneIntializingArrays = YES;
                [strongSelf.activityIndicatorView stopAnimating];
            });
        }
    });
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    if (!self.doneInitializingArrays) {
        [self.activityIndicatorView startAnimating];
    } 
}

There is absolutely no performance difference between viewDidLoad: and viewDidAppear:. Both are normal functions running on the main thread. If your initializeArrays method takes 3 seconds to load, it will take 3 seconds in whichever method you call it. Since you are not explicitly changing threads, any function in which you call initializeArrays will not exit until it's finished.

The call to [self.activityIndicatorView startAnimating] will basically "mark" the activityIndicatorView so that another UI function on the main thread will start it animating. (This is why the main or 'UI' thread is important, because all animations and visual updates to the screen are coordinated on it). So the function that will actually get the activityIndicator going doesn't get called until initializeArrays is finished and you have called "stopAnimating" already.

Try this:

- (void)viewDidLoad:(BOOL)animated{
    [super viewDidLoad];

    NSLog(@"viewDidLoad Entered");
    [self.activityIndicatorView startAnimating];

    partInput.delegate = self;
    brandInput.delegate = self;
    barcodeInput.delegate = self;
    itemNameInput.delegate = self;
}

- (void)viewDidAppear:(BOOL)animated{
    //initializeArrays is the function that initializes the arrays
    [self initializeArrays];
    [self.activityIndicatorView stopAnimating];
}

However, when you are loading things from a server(or heavy data processing), you also have to think about latency. If you pack all of your network communication into viewDidLoad or viewWillAppear, they will be executed before the user gets to see the view - possibly resulting a short freeze of your app. It may be good idea to first show the user an unpopulated view with an activity indicator of some sort. When you are done with your networking, which may take a second or two (or may even fail - who knows?), you can populate the view with your data. Good examples on how this could be done can be seen in various twitter clients. For example, when you view the author detail page in Twitterrific, the view only says "Loading..." until the network queries have completed.

ViewDidLoad calls only once when you initialized your ViewController but Viewdidapper calls every time.


The activityIndicatorViews will only animate if the main thread (the UI thread) is not busy. viewDidLoad: and viewDidAppear: are both executed on the main thread. If, as you mention, the initializeArrays method does not execute in a separate thread, then the activityIndicatorViews will never have time to animate.