Debugging is no doubt one of the most important skills that any effective developer has to have, no matter what language you program in.
The simplest form of debugging is, of course, printing out the output of the program and seeing if the output is what you expect it to be. However, if you put in print statements and then forget to remove them later, your code could end up dirty with these print statements. Another downside of just print statements is that you have to keep typing them in at each step of your code to really get to the bottom of the bug, and for each new print statement, you have to re-run your program again.
I’m currently working on replicating the Path app’s welcome screen, and I’m having a hard time getting the image animation to work in sync with the scrolling of my collection view. So for this post, I’ll be debugging my – (void)scrollViewDidScroll:(UIScrollView *)scrollView; delegate method.
Setting A Breakpoint
To put in a breakpoint, simply click to the left of your code in XCode. Very simple:
Now, run your code. Make sure your bottom pane is expanded into a split view. On the left, you’ll see all the variables in scope of your breakpoint printed out, and on the right you’ll see the words “lldb”. You can print out any variables in scope of the where the breakpoint is by just typing “po variable”. In my case, the variable is x, the horizontal content offset of the scrollview:
As you can see from the above image, in the bottom pane on the right it says that x is 0.5, and on the left, I printed it out and it’s 0.5 as well. Printing is usually easier than expanding the variables on the right side of the bottom pane. As you might notice, the “cellIndex” variable is currently 968322947, which is clearly not correct. That is because the line that the breakpoint stopped at has not yet been evaluated.
Line by Line
The nice thing about the debugger is that you can choose to click the play button on the bottom pane, or you can choose to walk through the code line by line, printing out the outputs of each variable in scope as you need. To see what the cellIndex is going to be evaluated to I’m simply going to step to go to the next line (aka “Step over”):
As you can see from me printing out the cellIndex before and after the step over, it has now been evaluated correctly to 0. Now, I can keep stepping over through the whole method, printing out variables as needed and seeing if they match what I expect. This is much easier and a lot more efficient than putting in endless log statements and rerunning the code, right?!
The problem with my current breakpoint in the scrollViewDidScroll: method is that this method gets called about 10 times, every time the view scrolls, and it’s annoying to stop the code every single time! Don’t worry, though, the breakpoint can be set to not stop the code, but still print out the variables you need. Simply right click on your breakpoint, and choose the “Edit Breakpoint” option:
On the edit screen, you can check the “Automatically continue after evaluating option”, so the breakpoint does not stop. However, you first want to make sure to add one or more “Actions” that happen during that point. The default action is the debugger command. For my purposes, I’m just going to print out x, so my debugger command will be “po x”.
However, another way to print out X, in a way that’s more like a Log statement is to choose the “Log Message” action option. In the log message, you can just put variables that need to be evaluated between two @ signs, for example: “Current X is @x@”, where the little x between the @ signs will be evaluated to the value of x. The Log Message option is really useful if you want to print out multiple variables at that breakpoint, and need to specify what they are:
Here is what is printed out when I run my program and scroll:
As you can see, the XCode debugger tool is very powerful, and I encourage you to use it!