In the program, whether you want to figure out why there are 3 objects in the array instead of 5, or why a new player starts, the game is backwards--debugging is a more important part of these processes. With this study, we will know most of the important debugging features that can be used in the program, and how to use these debugging features to help you solve bugs in less time.
This article will cover the following topics:
- To check the status of a program using the console
- Logging and mastering NSLog
- Tracking the use of memory using the object's life cycle
checking with the console
At the time of debugging, maybe the small black box at the bottom of Xcode will be your best friend. It can output log messages, error messages, and a variety of other useful content--which can help you track errors. In addition to seeing the output of the log, we can also stop at a breakpoint and examine the variable information in the program.
Breakpoint with conditional
This article assumes that you and know how breakpoints work (even if you don't know it, don't worry, after reading this article, you will understand!). )。
It is important to have a breakpoint at a particular point in time, and in some breakpoints it is sometimes necessary to pass a painful loop or recursive function to make our object equal to a certain value. At this point we can use conditional breakpoints!
A conditional breakpoint is a class of breakpoints where a breakpoint is hit only if a certain condition is satisfied. As you can imagine: we only want the breakpoint to be hit when the object is in a certain state, or when the loop iterates to the first nth. Click ' Gutter ' in the Xcode editor to add a breakpoint, right-click on the breakpoint, and select ' Edit Breakpoint ' to set a specific condition.
Conditionalbreakpoints
You can provide a condition (such as i==12), or the number of breakpoint misses. You can also add an action that can occur automatically based on a breakpoint, such as a debugger command--print a value.
Tip : The keyboard shortcut for adding/removing breakpoints is command+\
Another important breakpoint trick is to add an exception breakpoint (Exception breakpoint). When an exception is encountered, the basic 99% times Xcode will automatically go to the Autorelease pool in the main method.
Unhelpful_break
Thanks to Xcode ... It's so useful!
With an exception breakpoint, you can conveniently navigate to the exact line of code that caused the exception to occur. How to add an exception breakpoint: Open the Exception Breakpoint tab (COMMAND+6). Select the "+" button in the lower-left corner of the window and add a ' exception breakpoint ' so that when Xcode encounters an exception, a breakpoint stops at the place where the exception code is generated.
Exception-breakpoint
Manual Printing on the console
In general, we add breakpoints in our program code to see the state of a variable through the ' Variables view ' provided by Xcode, which is next to the console of the Xcode bottom. Theoretically, the window can display the status of all values related to the current context. In fact, this is a little bit of a problem, and sometimes after the breakpoint is over, the window does not make the relevant update.
Variables view
A good feature is that we can use the console's commands to check a particular object-this is very useful. Enter 'po' on the console to print the instant message of the specified object (using ' p ' when processing the scalar value).
Po_command
This is useful when viewing an object that already exists (nil if the object does not exist)-determining the object's value, viewing the array/dictionary information at run time, or even a comparison of two objects (this command can print out the memory address of the related object, we can print out the information of two objects, And see if they have the same memory address.
Also very useful (but hidden commands) can be very easy to check the view-therecursivedescription command-on the view of the command to print out the view of the inheritance relationship.
Recursivedescription
Log is valid
Sometimes we want to print the message to the console at a certain time during the debugging process, and you can use the NSLog function to print any output to the console. This feature is useful when you are not using breakpoints. NSLog conforms to the same format as the [NSString stringWithFormat] method.
Nslog_use
Tip : Here you can see information about string formatting in Objective-c: String programming Guide
make NSLog more intelligent
Although NSLog is very useful, any content printed from NSLog on the real machine will be preserved and hidden from everyone-just connect the device to your computer, open the organiser in Xcode, and navigate to the console to see each log message. Perhaps you will realize that this will bring some serious impact! Think about it if you put some secret algorithmic logic, or the user password to print to the console! So if Apple detects that in the production build, when it outputs a lot of content to the console, your app may be rejected by Apple to be listed on the store.
Nslog_public
Fortunately, here's one of the simplest ways to log--through a macro, so that NSLog only works when the debug build. Add this feature to a header file that can be accessed globally. This allows you to use log as you like, and does not include the log-related code when you are production. The following code:
#ifdef debug#define dmlog (...) NSLog (@ "%s%@", __pretty_function__, [NSString stringwithformat:__va_args__]) #else # define Dmlog (...) do {} while (0)
Now if you use Dmlog, log will only be printed during the debug build. The production build will not have any log at all. You can print out the function where the log is printed by __pretty_function\__ .
Next Step
Although NSLog is excellent, it has some limitations:
- Can only be printed locally
- Log with level is not supported (for example, critical, warning, etc.)
- NSLog efficiency is low. NSLog can seriously affect the execution efficiency of a program when it is heavily processed
There are also frameworks on the Internet that can be logged, and these frameworks can avoid some of the limitations of NSLog. Here are two good:
- Cocoa Lumberjack – This is a very well-known log framework for Cocoa. Although it's a bit hard to start with, it's very powerful.
- A substitute for snlog –nslog.
tracking the life cycle of an object
While ARC can effectively manage memory, it is still important to track some important events during the life of the object. After all, ARC does not completely eliminate the possibility of a memory leak, or make sure to access an object that has been released (arc is just trying to avoid this). To do this, we can use some methods and tools to observe and notice what the object is doing.
Log some important events
There are two important methods in the life cycle of a Objective-c object: Init and Dealloc. It is a good idea to log the events that are called by both methods to the console-you can observe the beginning of the object's life through the console, and more importantly, ensure that the object is freed.
-(ID) init{self = [super init]; if (self) { NSLog (@ '%@:%@ ', Nsstringfromselector (_cmd), self); } return self;} -(void) dealloc{ NSLog (@ "%@:%@", Nsstringfromselector (_cmd), self);}
static analyzers (analyzer) and inspectors
There are two tools in Xcode that you can use to clean up your code to reduce the error rate of your code. The static Analyzer tool can suggest improvements to our code, such as detecting objects that have not been used, and there are no release objects (ARC still has a problem with the core Foundation object). You can view the recommendations by selecting ' Anlayze ' in the Product menu.
Analyse
Inspectors are a very powerful set of tools that can not only check the memory usage of our program from different angles, but also the use of the file system (add, delete, modify, etc.), and even provide a way to automate UI interaction. You can view these inspectors by selecting ' profile ' in the Product menu.
Select ' Profile ' to open a instrument window, where you can select a configuration template to run. The most commonly used templates are zombies (discussed later), Activity monitor and leaks. Leaks is probably the most useful template for capturing memory leaks while the program is running.
screen-shot-2012-12-09-at-1.23.38-pm
Zombies is your friend.
Although it is difficult to encounter exc_bad_access errors in places where there is an arc, the error will still occur in certain situations. When working with Uipopovercontroller or core foundation objects, we can access an object that has been removed. In general, when we release an object in memory, the object is destroyed. However, when zombies is turned on, it simply marks the object as release, and the object is actually stuck in memory. When we visit a zombie object, Xcode can tell us that the object being accessed is an object that should not exist. Because Xcode knows what this object is, it allows us to know where the object is and when it happened.
Here are two ways to find out the Zombies object. Use the zombie configuration template in the inspector, or turn on the Zombie diagnostics option in the ' Run ' build option. Next to the Stop button, click the Scheme name, then select ' Edit Scheme ', click Diagnostic tab, and Tick ' Enable Zombie Objects '. Note that zombie can only be used in simulator debugging, not on the real machine.
Enabling-zombies
Conclusion
Hopefully these tips on debugging can help you. With these tips, you can help reduce the time it takes to fix bugs, and spend more time in important places-building great programs!
The above list is not a complete debugging technique. There are many other techniques that are not discussed, such as debugging problems in a real machine, remote bug reports, crash reports, and so on.
Good programming!