Chapter    13

Introducing the Xcode Debugger

Not only is Xcode provided free of charge on Apple’s developer site and the Mac App Store, but it is a great tool. Aside from being able to use it to create the next great Mac, iPhone, iPad, and Apple Watch apps, Xcode has a debugger built right into the tool.

What exactly is a debugger? Well, let’s get something straight—programs do exactly what they are written to do, but sometimes what is written isn’t exactly what the program is really meant to do. This can mean the program crashes or just doesn’t do something that is expected. Whatever the case, when a program doesn’t work as planned, the program is said to have bugs. The process of going through the code and fixing these problems is called debugging.

There is still some debate as to the real origin of the term bug, but one well-documented case from 1947 involved the late Rear Admiral Grace Hopper, a Naval reservist and programmer at the time. Hopper and her team were trying to solve a problem with the Harvard Mark II computer. One team member found a moth in the circuitry that was causing the problem with one of the relays. Hopper was later quoted as saying, “From then on, when anything went wrong with a computer, we said it had bugs in it.”1

Regardless of the origin, the term stuck, and programmers all over the world use debuggers, such as the one built into Xcode, to help find bugs in programs. But people are the real debuggers; debugging tools merely help programmers locate problems. No debugger, whatever the name might imply, fixes problems on its own.

This chapter highlights some of the more important features of the Xcode debugger and explains how to use them. Once you are finished with this chapter, you should have a good enough understanding of the Xcode debugger and of the debugging process in general to allow you to search for and fix the majority of programming issues.

Getting Started with Debugging

If you’ve ever watched a movie in slow motion just so you can catch a detail you can’t see when the movie is played at full speed, you’ve used a tool to do something a little like debugging. The idea that playing the movie frame by frame will reveal the detail you are looking for is the same sort of idea you apply when debugging a program. With a program, sometimes it becomes necessary to slow things down a bit to see what’s happening. The debugger allows you to do this using two main features: setting a breakpoint and stepping through the program line by line—more on these two features in a bit. Let’s first look at how to get to the debugger and what it looks like.

First you need to load an application. The examples in this chapter use the BookStore project from Chapter 8, so open Xcode and load the BookStore project.

Second, make sure the Debug build configuration is chosen for the Run scheme, as shown in Figure 13-1. To edit the current scheme, choose Product image Scheme image Edit Scheme from the main menu. Debug is the default selection, so you probably won’t have to change this. This step is important because if the configuration is set to Release, debugging will not work at all.

9781484214893_Fig13-01.jpg

Figure 13-1. Selecting the Debug configuration

While this book won’t discuss Xcode schemes, just know that by default Xcode provides both a Release configuration and a Debug configuration for any Mac OS X or iOS project you create. The main difference as it pertains to this chapter is that a Release configuration doesn’t add any program information that is necessary for debugging an application, whereas the Debug configuration does.

Setting Breakpoints

To see what’s going on in a program, you need to make the program pause at certain points that you as a programmer are interested in. A breakpoint allows you to do this. In Figure 13-2, there is a breakpoint on line 24 of the program. To set this, simply place the cursor over the line number (not the program text, but the number 24 to the left of the program text) and click once. You will see a small blue arrow behind the line number. This lets you know that a breakpoint is set.

9781484214893_Fig13-02.jpg

Figure 13-2. Your first breakpoint

If line numbers are not being displayed, simply choose Xcode image Preferences from the main menu, click the Text Editing tab, and select the Line Numbers checkbox.

You can also remove the breakpoint by dragging the breakpoint to the left or right of the line number column and then dropping it. In Figure 13-3, the breakpoint has been dragged to the left of the column. During the drag-and-drop process, the breakpoint will turn into a puff of smoke. You can also right-click (or Control-click) the breakpoint, and you will be given the option to delete or disable a breakpoint. Disabling a breakpoint is convenient if you think you might need it again in the future.

9781484214893_Fig13-03.jpg

Figure 13-3. Right-clicking a breakpoint

Setting and deleting breakpoints are pretty straightforward tasks.

Using the Breakpoint Navigator

With small projects, knowing where all the breakpoints are isn’t necessarily difficult. However, once a project gets larger than, say, your small BookStore application, managing all the breakpoints could be a little more difficult. Fortunately, Xcode provides a simple method to list all the breakpoints in an application; it’s called the Breakpoint Navigator. Just click the Breakpoint Navigator icon in the navigation selector bar, as shown in Figure 13-4.

9781484214893_Fig13-04.jpg

Figure 13-4. Accessing the Breakpoint Navigator in Xcode

Once you’ve clicked the icon, the navigator will list all the breakpoints currently defined in the application. From here, clicking a breakpoint will take you to the source file with the breakpoint. You can also easily delete and disable breakpoints from here.

To disable/enable a breakpoint in the Breakpoint navigator, click the blue breakpoint icon in the list (or wherever it appears). Don’t click the line; it has to be the little blue icon, as shown in Figure 13-5.

9781484214893_Fig13-05.jpg

Figure 13-5. Using the Breakpoint Navigator to enable/disable a breakpoint

It is sometimes handy to disable a breakpoint instead of deleting it, especially if you plan to put the breakpoint back in the same place again. The debugger will not stop on these faded breakpoints, but they remain in place so they can be conveniently enabled and act as a marker to an important area in the code.

It’s also possible to delete breakpoints from the Breakpoint Navigator. Simply select one or more breakpoints and press the Delete key. Make sure you select the correct breakpoints to delete since there is no undo feature.

It’s also possible to select the file associated with the breakpoints. In this case, if you delete the file listed in the Breakpoint Navigator and press Delete, all breakpoints in that file will be deleted.

Note that breakpoints are categorized by the file that they appear in. In Figure 13-5, the files are DetailViewController.swift and MasterViewController.swift, with the breakpoints listed below those file names. Figure 13-6 shows an example of what a file looks like with more than a single breakpoint.

9781484214893_Fig13-06.jpg

Figure 13-6. A file with several breakpoints

Debugging Basics

Set a breakpoint on the statement shown in Figure 13-2. Next, as shown in Figure 13-7, click the Run button to compile the project and start running it in the Xcode debugger.

9781484214893_Fig13-07.jpg

Figure 13-7. The Build and Debug buttons in the Xcode toolbar

Once the project builds, the debugger will start. The screen will show the debugging windows, and the program will stop execution on the line statement, as shown in Figure 13-8.

The Debugger view adds some additional windows. The following are the different parts of the Debugger view shown in Figure 13-8:

9781484214893_Fig13-08.jpg

Figure 13-8. The Debugger view with execution stopped on line 24

  • Debugger controls (circled in Figure 13-8) The debugging controls can pause, continue, step over, step into, and step out of statements in the program. The stepping controls are used most often. The first button on the left is used to show or hide the debugger view. In Figure 13-8, the debugger view is shown.
  • Variables: The Variables view displays the variables currently in scope. Clicking the little triangle just to the left of a variable name will expand it.
  • Console: The output window will show useful information in the event of a crash or exception. Also, any NSLog or print output goes here.
  • Debug navigator: The stack trace shows the call stack as well as all the threads currently active in the program. The stack is a hierarchical view of what methods are being called. For example, main calls UIApplicationMain, and UIApplicationMain calls the UIViewController class. These method calls “stack” up until they finally return.

Working with the Debugger Controls

As mentioned previously, once the debugger starts, the view changes. What appears are the debugging controls (circled in Figure 13-8). The controls are fairly straightforward and are explained in Table 13-1.

Table 13-1. Xcode Debugging Controls

Control

Description

9781484214893_unFig13-01.jpg

Clicking the Stop button will stop the execution of the program. If the iPhone or iPad emulator is running the application, it will also stop as if the user clicked the Home button on the device. Clicking the Run button (looks like a Play button) starts debugging. If the application is currently in debug mode, clicking the Run button again will restart debugging the application from the beginning; it’s like stopping and then starting again.

9781484214893_unFig13-02.jpg

Clicking this causes the program to continue execution. The program will continue running until it ends, the Stop button is clicked, or the program runs into another breakpoint.

9781484214893_unFig13-03.jpg

When the debugger stops on a breakpoint, clicking the Step Over button will cause the debugger to execute the current line of code and stop at the next line of code.

9781484214893_unFig13-04.jpg

Clicking the Step In button will cause the debugger to go into the specified function or method. This is important if there is a need to follow code into specific methods or functions. Only methods for which the project has source code can be stepped into.

9781484214893_unFig13-05.jpg

The Step Out button will cause the current method to finish executing, and the debugger will go back to the caller.

Using the Step Controls

To practice using the step controls, let’s step into a method. As the name implies, the Step In button follows program execution into the method or function that is highlighted. Select the DetailViewController.swift file on the left side. Then set a breakpoint on line 36, which is the call to self.configureView(). Click the Run button and select a book from the list. Your screen should look similar to Figure 13-9.

9781484214893_Fig13-09.jpg

Figure 13-9. The debugger stopped on line 38

Click the Step Into button, 9781484214893_unFig13-06.jpg which will cause the debugger to go into the configureView() method of the DetailViewController object. The screen should look like Figure 13-10.

9781484214893_Fig13-10.jpg

Figure 13-10. Stepping into the configureView method of the DetailViewController object

The control Step Over, 9781484214893_unFig13-07.jpg, continues execution of the program but doesn’t go into a method. It simply executes the method and continues to the next line. Step Out, 9781484214893_unFig13-08.jpg, is a little like the opposite of Step In. If the Step Out button is clicked, the current method continues execution until it finishes. The debugger then returns to the line before Step In was clicked. For example, if the Step In button is clicked on the line shown in Figure 13-9 and then the Step Out button is clicked, the debugger will return to the viewDidLoad() method of the DetailViewController.swift file on the statement shown in Figure 13-9 (line 36 in the example), which was the line where Step In was clicked.

Looking at the Thread Window and Call Stack

As mentioned earlier, the Debug navigator displays the current thread. However, it also displays the call stack. If you look at the difference between Figures 13-9 and 13-10 as far as the thread window goes, you can see that Figure 13-10 has the configureView method listed because DetailViewController calls the configureView method.

Now, the call stack is not simply a list of functions that have been called; rather, it’s a list of functions that are currently being called. That’s an important distinction. Once the configureView method is finished and returns (line 31), configureView will no longer appear in the call stack. You can think of a call stack almost like a breadcrumb trail. The trail shows you how to get back to where you started.

Debugging Variables

It is possible to view some information about a variable (other than its memory address) by hovering over the variable in the code. When you get to where the value of a variable has been assigned in the local scope, you will see the variable in the bottom Variables view. In Figure 13-11, you can see the newBook variable, and it has a title of Swift for Absolute Beginners. You can also see that there is no author or description assigned. In debugging, when you are stopped on a line, it is before the line is executed. This means that even though you are paused on the line to assign the author property, it has not been assigned yet.

9781484214893_Fig13-11.jpg

Figure 13-11. Viewing a variable value

Position the cursor over any place the newBook variable appears and click the disclosure triangle to display the Book object. You should see what is displayed in Figure 13-12.

9781484214893_Fig13-12.jpg

Figure 13-12. Hovering over the newBook variable reveals some information

Hovering over the newBook variable reveals its information. In Figure 13-12, you can see the newBook variable expanded.

Dealing with Code Errors and Warnings

While coding errors and warnings aren’t really part of the Xcode debugger, fixing them is part of the entire debugging process. Before a program can be run (with or without the debugger), all errors must be fixed. Warnings won’t stop a program from building, but they could cause issues during program execution. It’s best not to have warnings at all.

Errors

Let’s take a look at a couple of types of errors. To start, let’s add an error to the code. On line 15 of the MasterViewController.swift file, change the following:

var myBookStore: BookStore = BookStore()

to the following:

var myBookStore: BookStore = BookStore[]

Save the changes and then build the project by pressing flower.jpg+B. There will be an error, as shown in Figure 13-13, that may show up immediately or after the build.

9781484214893_Fig13-13.jpg

Figure 13-13. Viewing the error in Xcode

Next, move over to the Issue Navigator window, as shown in Figure 13-14, by clicking the triangle with the exclamation point. This view shows all the errors and warnings currently in the program—not just the current file, MainViewController.swift, but all the files. Errors are displayed as a white exclamation point inside a red octagon. In this case, you have one error. If the error doesn’t fit on the screen or is hard to read, simply hover over the error on the Issue Navigator, and the full error will be displayed.

9781484214893_Fig13-14.jpg

Figure 13-14. Viewing the Issue Navigator

Generally, the error points to the problem. In the previous case, the BookStore object was initialized as an array rather than as an object.

Go ahead and fix the error by changing [] to ().

Warnings

Warnings indicate potential problems with the program. As mentioned, warnings won’t stop a program from building but may cause issues during program execution. It’s outside the scope of this book to cover those warnings that may or may not cause problems during program execution; however, it’s good practice to eliminate all warnings from a program.

Add the following code to the MasterViewController.swift viewDidLoad method:

if (false){
   print("False")
}

The print command will never be executed because false will never be equal to true. Build the project by pressing flower.jpg+B. A warning will be displayed, as shown in Figure 13-15.

9781484214893_Fig13-15.jpg

Figure 13-15. Viewing the warnings in the Issue Navigator

Clicking the first warning in the Issue Navigator will show you the code that is causing the first problem, as shown in Figure 13-16.

9781484214893_Fig13-16.jpg

Figure 13-16. Viewing your first warning

In the main window, you can see the warning. In fact, this warning gives you a clue as to the problem with the code. The warning states the following:

“Will never be executed”

This is a simple example of a warning. You can receive warnings for many things such as unused variables, incomplete delegate implementations, and unexecutable code. It is good practice to clean up the warnings in your code to avoid issues down the road.

Summary

This chapter covered the high-level features of the free Apple Xcode debugger. Regardless of price, Xcode is an excellent debugger. Specifically, in this chapter, you learned the following:

  • The origins of the term bug and what a debugger is
  • The high-level features of the Xcode debugger, including breakpoints and stepping through a program
  • How to use the debugging controls called Continue, Step Over, Step In, and Step Out
  • Working with the various debugger views, including threads (call stack), Variables view, Text editor, and Console Output
  • Looking at program variables
  • Dealing with errors and warnings

______________________

1Michael Moritz, Alexander L. Taylor III, and Peter Stoler, “The Wizard Inside the Machine,” Time, Vol.123, no. 16: pp. 56–63.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset