Here's how to use instruments to find memory leaks in programs and use nszombieenabled settings without arc.
This article assumes that you are already familiar with the OBJ-C memory management mechanism.
Experimental development environment: XCode 4.5.2
1. Run Demo
Download a demo that implements a ready-to-go memory leak: Leak app
Download down, open run, the program is a sushi list that lists various sushi rolls. Try to choose a few lines inside, it should be the second row when the collapse. Collapse:
In the collapse of the place, know crash place, but do not know the reason for the specific crash.
2. Set nszombieenabled
This is a "exc_bad_access" error. We open the Xcode option: "Nszombieenabled". You may be given more tips when crash.
Setup steps: 1
2: Check the red box.
Run, select the cell in the operation as you just did. Crash again, this time in the Output window you will see an additional error message:
1 |
2012-11-28 13:22:08.911 PropMemFun[2132:11303] *** -[CFString respondsToSelector:]: message sent to deallocated instance 0x713ebc0 |
It probably means: send a message to the freed memory. In other words, the freed memory is used, which is equivalent to using the "wild pointer" in the C language.
Look at the next crash this statement, sushistring should be no problem, it is initialized from the stringWithFormat. That's the problem with _lastsushiselected.
_lastsushiselected points to the sushistring,sushistring is a autorelease variable. In the second click, Sushistring has been released, so crash. Keep it for _lastsushiselected, you can use it. The code is modified as follows:
1 |
_lastSushiSelected = [sushiString retain]; |
Run, and this time does not crash.
3. Analyze memory leaks (SHIFT+COMMAND+B)
The app isn't crash, so see if there's a memory leak. With Xcode's analyze, you can analyze where there's a memory leak.
After analysis, you can see:
Here is a hint that Alertview is not released, there is a memory leak, then we release
Further analysis, this problem solved.
4. Using Instruments's leaks tool
The analysis of memory leaks does not reveal all memory leaks, and some memory leaks are generated when the user is operating at runtime. Then we need to use the instruments.
According to the above operation, build success out of the instruments tool, select the leaks option, this time the sushi program is also running, check the list of items, drag, and so on, the tool shows the following:
As you can probably guess, a red pillar indicates a memory leak. How did you see the leak through this tool?
Start by pressing the Red Circular button on the toolbar to stop the tool monitoring memory activity. Select Leak, then click the Middle cross to cross that, select Call Tree.
The option to call tree in the lower left corner is optional. Select Invert call Tree and hide System Libraries, as shown below:
The specific code for the memory leak is found, and the red box on the right specifies which method has a memory leak.
You just double-click on these methods, will jump to the specific code, haha, is not very convenient.
Here should be a hint 100% memory will leak.
6. Resolve Memory leaks
The problem is found, so solve it.
About: Tableview:didselectrowatindexpath, analyzing its memory process:
The sushistring variable is created by Autorelease and its reference count is 1.
This line of code causes the reference count to increase to 2, _lastsushiselected = [sushistring retain];
At the end of this method, Sushistring's autorelease takes effect, and the reference count for this variable is reduced to 1.
When the Tableview:didselectrowatindexpath method is executed again, _lastsushiselected is assigned a new pointer, the old _lastsushiselected reference count is still 1, not released, A memory leak has been generated.
How to solve it?
In _lastsushiselected = [sushistring retain]; Before the original release is OK:
12 |
[_lastSushiSelected release]; _lastSushiSelected = [sushiString retain]; |
About: Tableview:cellforrowatindexpath
This is more obvious, Sushistring was alloc and after the Init is not released, you can use stringWithFormat to invoke Autorelease, the code is as follows:
1 |
NSString *sushiString = [NSString stringWithFormat:@ "%d: %@" , indexPath.row, sushiName]; |
OK, leaks are fix, and then use the tool analysis to see, this time you point, and then drag, and how to operate, there is no memory leaks. Indicates that the memory leak is blocked.
Debug iOS Memory leak resolution