Debugging The best way to eliminate bugs is not to create them in the first place. That sounds simplistic, but every bit of forethought applied to programming will pay off in time saved tracking bugs later. The compiler will help by issuing errors and warnings. An error prevents the build process from completing and must be fixed. Errors are usually caused by errors in syntax. A warning will allow the build to complete. It may indicate a problem that must be fixed or merely something that is suspicious but acceptable. A common source of warnings is typographical errors. A misspelled method name is not an error, but the compiler may issue a warning like "This class may not respond to -nameOfMessage". Obj-C waits until runtime to find the method. If it isn't found a crash is possible. Watch for those. Unless you really know what is happening that is as good as an error. Here is a project that demonstrates some of the things discussed here. Static Analyzer As you enter code, Xcode continually scans it for problems of syntax and meaning. It will warn you of uninitialized variables, unused variables, failure to return a value, methods that may fail, and many other things. NSLog() An NSLog statement sends a string of text to the console when it is executed. The string can include values from the code. NSLog(@"The row is:%i", indexPath.row); The console in Xcode 4 is at the bottom right of the main editor window. Buttons there let you choose to see variable values, the console or both. NSLog statements should not appear in shipping code. Apple will reject apps that use them. assert() assert() evaluates a boolean expression. If it is true, execution continues. If it is false, the program halts at that line and issues a log message. assert(x < XMAX); You use asserts to catch "hard" errors, things that absolutely must not happen, for example an array index exceeding its bounds. "Soft" errors from which you can recover, like file not found, or network transfer failed, must be dealt with by the code. assert() is a POC (Plain Old C) macro defined in usr/include/assert.h. They usually remain in the code. You remove their effect (turn them off) by putting this line, #define NDEBUG before #import <Foundation/Foundation.h> in the .pch header file. You turn them on for testing and turn them off for shipping. Objective C offers a similar NSAssert() function, but it is more complicated, and I prefer the more direct assert(). Breakpoints A breakpoint is a marker you can put on a line of code. Nothing is written into the code, but the system notes where it is, and when you run the program it will halt when it reaches the breakpoint. You can have as many breakpoints as you wish. When execution is suspended, you will see the source code where it has stopped. You can examine the values of variables, change them if you wish, step forward one line at a time, step into subroutines or simply step over them and continue execution. You can use breakpoints on the Simulator or on a device. You should always compile a debug version of the program. That will build in various hooks the debugger will use to track values and halt at the right point. Debugging with a release version is usually fruitless. While stopped at a breakpoint you can ctrl-click on a variable to show a popup menu. One choice is "Watch variable". If you select that and continue execution, the program will stop when the value of the variable is changed. Instruments (Leaks, Performance) Instruments is a sophisticated set of tools. With them you can find memory leaks and measure the performance of the program, among many other things. The Instruments User Guide is here. The Instruments User Reference is here. Don't go there until you have read the Guide. Furthermore, there is a tech note on advanced debugging. The page was last updated
Thursday, May 3, 2012 11:39 AM
|