Background information (class definition and class instance)
An important concept here is the difference between a class definition and an instance of a class.
The class definition is the source code for the class. For example, ViewController.m contains a definition for the myViewController class, and AppDelegate.m contains a definition for the AppDelegate class. Another class mentioned in your question is UIApplication . This is a system class, i.e. You do not have source code for this class.
A class instance is a piece of memory on the heap and a pointer to that memory. A class instance is usually created using a line of code like this
myClass *foo = [[myClass alloc] init];
Notice that alloc reserves heap space for the class, and then init sets the initial values ββfor the class variables / properties. The pointer to the instance is then stored in foo .
When your application starts, the following sequence of events occurs (roughly):
- the system creates an instance of the UIApplication class
- a pointer to a UIApplication instance is stored somewhere in the system variable
- the system creates an instance of the class AppDelegate
- a pointer to AppDelegate is stored in a variable called
delegate in the UIApplication instance - the system creates an instance of the MyViewController class
- a pointer to the MyViewController class is stored somewhere
Storing a pointer to a MyViewController is where things get messy. The AppDelegate class has a UIWindow property called window . (You can see this in AppDelegate.h.) If the application has only one view controller, a pointer to this view controller is stored in the window.rootViewController property. But if the application has several view controllers (under the control of UINavigationController or UITabBarController), then everything becomes more complicated.
Spaghetti Code Solution
So, the problem you are facing is this: when the system calls the applicationDidEnterBackground method, how do you get a pointer to the view controller? Well, technically, the application delegate has a pointer to a view controller somewhere under the window property, but there is no easy way to get that pointer (assuming the application has more than one view controller).
In another thread, an approach to the problem of spaghetti was proposed. (Note that the spaghetti codes approach was proposed only because the OP in this other thread did not want to do something correctly with notifications.) Here, how the spaghetti code works
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; appDelegate.myViewController = self;
This code retrieves a pointer to a UIApplication instance created by the system, and then queries the delegate property to get a pointer to an AppDelegate instance. A pointer to self , which is a pointer to an instance of MyViewController, is then stored in the AppDelegate property.
A pointer to an instance of MyViewController can then be used when the system calls applicationDidEnterBackground .
The right decision
The correct solution is to use notifications (as in kkumpavat's answer)
- (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil]; } - (void)didEnterBackground { NSLog( @"Entering background now" ); } -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; }
With notifications, you do not save redundant pointers to view controllers, and you do not need to determine where the system has saved a pointer to your view controller. addObserver calling addObserver for UIApplicationDidEnterBackgroundNotification , you tell the system to directly contact a controller of the kind didEnterBackground .