Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Beginning iOS5 Development.pdf
Скачиваний:
7
Добавлен:
09.05.2015
Размер:
15.6 Mб
Скачать

CHAPTER 15: Grand Central Dispatch, Background Processing, and You

543

applicationDidEnterBackground: is where your app should free all resources that can be re-created later, save all user data, close network connections, and so on. This is also the spot where you can request more time to run in the background if you need to, as we’ll demonstrate shortly. If you spend too much time doing things in applicationDidEnterBackground:—more than about five seconds—the system will decide that your app is misbehaving and terminate it. You should implement applicationWillEnterForeground: to re-create whatever was torn down in applicationDidEnterBackground:, such as reloading user data, reestablishing network connections, and so on. Note that when applicationDidEnterBackground: is called, you can safely assume that applicationWillResignActive: has also been recently called. Likewise, when applicationWillEnterForeground: is called, you can assume that applicationDidBecomeActive: will soon be called as well.

Last in the list is applicationWillTerminate:, which you’ll probably use seldom, if ever. Prior to iOS 4, this was the method you would implement to save user data and so on, but now that applicationDidEnterBackground: exists, we don’t need the old method. It is called only if your application is already in the background and the system decides to skip suspension for some reason and simply terminate the app.

Now, you should have a basic theoretical understanding of the states an application transitions between. Let’s put this knowledge to the test with a simple app that does nothing more than write a message to Xcode’s console log each time one of these methods is called. Then we’ll manipulate the running app in a variety of ways, just as a user might, and see which transitions occur.

Creating State Lab

In Xcode, create a new project based on the Single View Application template, and name it State Lab. This app won’t display anything but the default gray screen it’s born with. All the output it’s going to generate will end up in the Xcode console instead. The BIDAppDelegate.m file already contains all the methods we’re interested in. We just need to add some logging, as shown in bold. Note that we’ve also removed the comments from these methods, just for the sake of brevity.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions

{

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch.

NSLog(@"%@", NSStringFromSelector(_cmd));

self.viewController = [[BIDViewController alloc] initWithNibName:@"BIDViewController" bundle:nil];

self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible];

return YES;

}

- (void)applicationWillResignActive:(UIApplication *)application

{

www.it-ebooks.info

544

CHAPTER 15: Grand Central Dispatch, Background Processing, and You

NSLog(@"%@", NSStringFromSelector(_cmd));

}

- (void)applicationDidEnterBackground:(UIApplication *)application

{

NSLog(@"%@", NSStringFromSelector(_cmd));

}

- (void)applicationWillEnterForeground:(UIApplication *)application

{

NSLog(@"%@", NSStringFromSelector(_cmd));

}

- (void)applicationDidBecomeActive:(UIApplication *)application

{

NSLog(@"%@", NSStringFromSelector(_cmd));

}

- (void)applicationWillTerminate:(UIApplication *)application

{

NSLog(@"%@", NSStringFromSelector(_cmd));

}

You may be wondering about that NSLog call we’re using in all these methods. Objective- C provides a handy built-in variable called _cmd that always contains the selector of the current method. A selector, in case you need a refresher, is simply Objective-C’s way of referring to a method. The NSStringFromSelector function returns an NSString representation of a given selector. Our usage here simply gives us a shortcut for outputting the current method name without needing to retype it or copy and paste it.

Exploring Execution States

Now, build and run the app. The simulator will appear and launch our application. Switch back to Xcode and take a look at the console (View Debug Area Activate Console), where you should see something like this:

2011-10-31 11:56:52.674 State Lab[83116:f803] application:didFinishLaunchingWithOptions:

2011-10-31 11:56:52.677 State Lab[83116:f803] applicationDidBecomeActive:

Here, you can see that the application has successfully launched and been moved into the Active state. Now, go back to the simulator and press the home button, and you should see the following in the console:

2011-10-31 11:56:55.874 State Lab[83116:f803] applicationWillResignActive:

2011-10-31 11:56:55.875 State Lab[83116:f803] applicationDidEnterBackground:

These two lines show the app actually transitioning between two states: it first becomes Inactive and then goes to Background. What you can’t see here is that the app also switches to a third state: Suspended. Remember that you do not get any notification that this has happened; it’s completely outside your control. Note that the app is still live in some sense, and Xcode is still connected to it, even though it’s not actually getting any CPU time. Verify this by tapping the app’s icon to relaunch it, which should produce this output:

www.it-ebooks.info

 

CHAPTER 15: Grand Central Dispatch, Background Processing, and You

545

2011-10-31

11:57:00.886 State Lab[83116:f803] applicationWillEnterForeground:

 

2011-10-31

11:57:00.888 State Lab[83116:f803] applicationDidBecomeActive:

 

There you are, back in business. The app was previously Suspended, is woken up to

 

Inactive, and then ends up Active again. So, what happens when the app is really

 

terminated? Tap the home button again, and you’ll see this:

 

2011-10-31

11:57:03.569 State Lab[83116:f803] applicationWillResignActive:

 

2011-10-31

11:57:03.570 State Lab[83116:f803] applicationDidEnterBackground:

 

Now double-tap the home button. The shelf of apps should appear. Press and hold the State Lab icon until the little “kill” icon (the minus in a red circle) comes up. Press the kill icon to terminate State Lab. What happens? You may be surprised to see that none of our NSLog calls print anything to the console. Instead, Xcode itself prints a somewhat cryptic line like sharedlibrary apply-load-rules all before leaving you with a (gdb) prompt. At this point, State Lab is truly and completely terminated.

As it turns out, the applicationWillTerminate: method isn’t normally called when the system is moving an app from Suspended to Not Running state. When an app is Suspended, whether the system decides to dump it to reclaim memory or you manually force-quit it, the app simply vanishes and doesn’t get a chance to do anything. The applicationWillTerminate: method is called only if the app being terminated is in the Background state. This can occur, for instance, if your app is actively running in the Background state, using system resources in one of the predefined ways (audio playback, GPS usage, and so on) and is force-quit either by the user or by the system. In the case we just explored with State Lab, the app was in the Suspended state, not Background, and was therefore terminated immediately without any notification.

There’s one more interesting interaction to examine here. It’s what happens when the system shows an alert dialog, temporarily taking over the input stream from the app and putting it into an Inactive state. This state can be readily triggered only when running on a real device instead of the simulator, using the built-in Messages app. Messages, like many other apps, can receive messages from the outside and display them in several ways.

To see how these are set up, run the Settings app on your device, choose Notifications from the list at the upper left, and then select the Messages app from the list of apps on the right. The hot new way to show messages in iOS 5 is called Banners. This works by showing a small banner overlaid at the top of the screen, which doesn’t need to interrupt whatever app is currently being run. What we want to show is the bad old Alerts method, which makes a modal panel appear in front of the current app, requiring a user action. Select that, so that the Messages app turns back into the kind of pushy jerk that users of iOS 4 and below always had to deal with.

Now back to your computer. In Xcode, use the popup at the upper left to switch from the simulator to your device, and then hit the Run button to build and run the app on your device. Now, all you need to do is send a message to your device from the outside. If your device is an iPhone, you can send it an SMS message from another phone. If it’s an iPod touch or an iPad, you’re limited to Apple’s own iMessage communication, which works on all iOS 5 devices (including the iPhone). Figure out what works for your setup, and have someone else send your device a message via SMS or iMessage. When your

www.it-ebooks.info

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]