iOS tutorial instruments to test your app

Source: Internet
Author: User
Tags stack trace

Getting StartedIn order to save everyone's time, provide a demo of the demo to everyone.Code Portal.Download and unzip and open with Xcode. After compiling and running the app and entering any words in the search box, click on the results you will see the following results as you can see, this app is very simple. The program actually calls the Flickr API, and after searching through the search box at the top of the app, the search term in the following TableView displays your search terms. After searching for the number of search results in parentheses, click on the line to enter a slightly larger list of results. Click on one line to enter the image of the large map mode, on this page you can rotate the image as needed. So far the page looks pretty much, and you might think you should be able to submit appstore directly. The next article will teach you instruments tools to improve the performance and stability of your app. "Time Detector"The World martial arts, only fast not broken. Many companies believe in this dogma. The app's compaction cycle can be squeezed to the minimum, which leads to a lot of problems in the development, a bit of experience with the engineer sloppy optimization, and worse, the inexperienced engineers will not even optimize the app. In some ways, performance optimizations can be overlooked in your development process. Ten years ago, the hardware resources of mobile devices were very limited. Even floating-point numbers are banned. Because floating-point numbers can cause the code to become larger and slower to calculate. With the rapid development of science and technology, hardware can largely compensate for the software's short board. Now the mobile device 3D hardware processing efficiency is even comparable to the PC, but you can not always rely on hardware and processor speed to cover up your app to do more garbage. (What if Android is running on the iphone as smooth as iOS?) The concept of performance is very well drawn, so we have to rely on the graphical output of the data. You may spend a week optimizing an interesting algorithm, but this algorithm only accounts for 0.5% of the total execution time, No matter how much energy you spend trying to optimize it, no one will notice. Instead of a for loop that takes 90% of the time, you can improve the efficiency by slightly modifying it by 10%, which is a simple modification that can I got a lot of goodwill from everyone. Because. The first thing they feel when they run the app is that they're much faster than before. No one's going to care what you're modifying is a much better algorithm, or a simple for loop.What does this mean?   Instead of taking the time to optimize small details, it's better to find the place where you changed the optimization .  the first tool "Time Event Viewer" (your own fictional name, English-time Profiler),——— He can measure time intervals, interrupt program execution, Keep track of each thread's stack. You can imagine that when you press the pause screen when Xcode is debugging   For example, 100 samples are doing 1 millisecond intervals, and then there are 10 samples at the top of a method stack, you can figure out that the approximate time is 10% 10 milliseconds spent in this method, This is an approximate value .  nonsense less say, time is a detected.   Select Product-profile from the Xcode menu, or select the program to start instruments, you will see a selection window   This is instruments all the test instrument panel, select "Timer Profilter "Click Profile" back to Qidong simulator and app, you will be asked to enter the password once so that instruments can have permission to intercept the process. In the tool window, you can see the time count and leave a small arrow moving to the right of the graphic above the center of the screen. This indicates that the application is running.   Now start running the app and search for some pictures, and you find that finding a result is too slow, and the Search results list page is too much to put up with.   First, make sure that the view in the toolbar selects all of the three options selected, as shown below:   This will ensure that all panels are open. Now, study the explanations below and each of the sections below it: 1. Recording button. The middle of the red button will stop with the startup it is clicked on when the application is currently being analyzed. Note that this is actually stopping and starting the application instead of pausing it.   2. Run the timer and run the navigation, the timer shows how long the app has been running, and the arrows can be moved between them. If you stop and then use the Record button to restart the application, this will start a new run. The display will display "Run2 of 2", you can go back to the first run of data, first you stop the current run, and then press the left arrow back.   3. Run the track.  4. The expansion panel, in the case of a time-sniffing instrument, is used to track the display stack.   5. Panel in detail. It shows the main information about the instrument you are using, which is the most frequently used department, from which you can see the time    6 the CPU is running. Options panel, described later. The   plays come.   DelvePerform an image search and delve into the results. I personally like to look for "dog", of course you can also choose any content you want. Like a cat, a beautiful girl, something. Now scroll up and down the list, let the time detector measure the data, and pay attention to the changes and values of the screen. These values reflect the CPU cycle. But you may find that the following values are too many to see your dazzling. The following configuration options are described below, which opens the call tree on the left and then follows the following configuration:separate by thread: each thread should be considered separately. Only in this way can you pull out the heavy threads that consume a lot of CPU Invert call Tree: From the top down the trace stack, which means that the method you see in the table will have been sampled from frame No. 0, which is usually what you want, so you can see the most time-out method in the CPU. That is, funca{funb{func}} Tick the stack with c->b-a to show the deepest C at the outermost level of the call Hide Missing Symbols: If dSYM can't find your app or system frame, you can't see the method name in the table, only 16 binary values are visible, and if this item can hide the symbols, it's easy to simplify the data Hide System Libraries: Check this to show your app's code, which is very useful. Because usually you only care about the time the CPU spends on its own code, not on the system . Show Obj-c only: Show OC code only, if your program is a program like OpenGL, do not tick sideways because he might be C + + Flatten recursion: recursive function, one entry per stack traceTop Functions: The sum of the time that a function spends directly in the function, and the total time it takes for the function to call the function. Therefore, if function A calls B, then A's time is reported in a time spent plus B. It's really useful to spend the time, because it allows you to pick the maximum number of times each time you go down to the call stack, zeroing in on your most-time-consuming method. If you have enabled the above options, although some values may be slightly different, the order of the following results should be similar to the following table: Through the above you can see that most of the time spent in updating the form of photos. Double-click on this line and you will see the following then this is interesting, isn't it! Almost three-fourths of the time spent in Setphoto: methods are spent creating image data for photos! Now you can see what the problem is, the NSData's Datawithcontentsofurl method does not return immediately, because to go to the data from the Internet, each call takes up to a few seconds to return, and this method runs in the main thread, it is conceivable what results. In fact, in order to solve this problem, the class provides a Imagecache method for the background asynchronous download. Now you can switch to Xcode and manually locate the file, but the instrument has a handy "open Xcode" button right in front of you. Find its panel just above the code and click it: Want to modify the following
  1. -(void) Setphoto: (Flickrphoto *) Photo {
  2. _photo = photo;
  3. Self.textLabel.text = Photo.title;f
  4. NSData *imagedata = [NSData Datawithcontentsofurl:_photo.thumbnailurl];
  5. Self.imageView.image = [UIImage imagewithdata:imagedata];
  6. [[Imagecache Sharedinstance] Downloadimageaturl:_photo.thumbnailurl
  7. completionhandler:^ (UIImage *image) {
  8. Self.imageView.image = image;
  9. [Self setneedslayout];
  10. }];
  11. }
Modify the application Product-profile (or cmd-Remember that these shortcuts will really save you some time) after the instrument is re-run. Please note that this time will ask again if you are using together. This is because you also have a window to open this program, and the instrument assumes you want to run again with the same options. Perform some more searches, and note that the user interface is not so much at this time! These images are now loaded asynchronously and cached in the background, so once they have been downloaded once they do not have to be downloaded again. It looks great! Is it time to release it? Of course it's not.Assign, assign , assignThe next instrument is the distribution tool. It gives you all the details of all the memory you create and store them, and it also shows that you keep a count of each object. Turn off the instrument, go back to Xcode and select Product->profile. Then, assign from selector and click Profile. such as: The program opens again and you will see that this time you will find two tracks. One is called (assigned) allocations, and one is called VM Tracker (virtual machine tracking). This allocation track will be discussed in detail in this tutorial; Virtual machine Tracing is also useful, but more complex. so your mistakes are going to be tracked down?   have hidden items, you may not know there is something there. You may have heard of a memory leak. But what you may not know is that there are actually two kinds of leaks.   The first is a true memory leak, an object that has not been released, but is no longer referenced. Therefore, the memory cannot be reused.   The second type of leakage is more troublesome. This is called "unbounded memory Growth". This occurs when the memory continues to be allocated and never has the opportunity to be released.   If it goes on forever, your program will take up an infinite amount of memory, and when it exceeds a certain memory, it will be killed by the system's watchdog. .  create a scene where you can detect unlimited memory growth. First, the application makes 10 different searches (do not use an already existing search). Make sure to search for some results! Now let the program wait a few seconds.   You should have noticed that the orbital graph in the distribution is constantly rising. This is telling you that the memory has been allocated. It's this feature that will guide you to find unlimited memory growth.   What you are going to do is "heap shot analysis". To do this, press the button called "Mark Heap". You will find the detail panel to the left of the button press it and you will see a red sign appearing on the track, like this:  heap shot analysis is designed to perform an action multiple times to see if memory is growing indefinitely. Search for a content, wait a few seconds to load the image, and then return to the home page. Then mark the heap again. Repeat this to do different searches. After a few searches, the instrument will look something like this: you should be wondering. The blue in the picture is going on, you continue to do this 10 times the search for blue is still getting taller:  that must be bad. Don't worry, what's the memory warning? You know all this, right? Memory warning is to tell an application that memory warnings are the best way for iOS to process apps, especially when memory is getting tighter and you need to clear some memory.   Memory has been growing in fact not necessarily your code in addition to the problem, it is possible that the Uikit system framework itself leads to .  by selecting hardwaresimulate Memory Warning in the iOS Emulator's menu bar to simulate memory warnings. You will find that memory usage comes down slightly, but definitely not back to what it should be. So there is an infinite amount of memory where the growth takes place.   The reason that heap shots do the drilling search for each iteration, you can see the memory allocated between each shot. Take a look at the details panel and you'll see a bunch of shots.   Select the Hardwaresimulate memory warning in the menu bar of the iOS emulator to simulate a memory warning. You'll notice a slight drop in memory usage, but certainly not back where it should be.   After searching for each timeDo you can see the allocation between the memory has been shot. Take a look at the details panel and you'll see a lot of shots.   steady and ruthlessThe first heap lens as a reference, and then casually open a heap of shots, you will see as follows: By, this is a very big object! Where do you start looking? The best way to do this is by listing the classes that you use directly in your application. In this case, Httpheaderdict,cgregion,cgpath,cfnumber, and so on, can be ignored. However, one of the highlights is UIImage, which is definitely used in your program. Click on the arrow on the left of UIImage to display the full list. Select one, in the extension details panel: The gray is the system library, the black part is your application code, to get this tracking more context, double-click the unique black box Imagecache method, this time will be reversed to the following method
  1. -(void) Downloadimageaturl: (nsurl*) URL Completionhandler: (imagecachedownloadcompletionhandler) Completion {
  2. UIImage *cachedimage = [self imageforkey:[url absolutestring];
  3. if (cachedimage) {
  4. Completion (cachedimage);
  5. } Else {
  6. Dispatch_async (Dispatch_get_global_queue (dispatch_queue_priority_default, 0), ^{
  7. NSData *data = [NSData Datawithcontentsofurl:url];
  8. UIImage *image = [UIImage imagewithdata:data];
  9. [Self setimage:image forkey:[url absolutestring];
  10. Dispatch_async (Dispatch_get_main_queue (), ^{
  11. completion (image);
  12. });
  13. });
  14. }
  15. }
Tools are very useful, and you now have to try to think through your own code what's going on. Look through the above method, you will see that it calls a method named SetImage: Forkey:. This method is cached in case it is used again after the image of the application. Ah! Then this certainly sounds like it might be a problem! Let's take a look at the implementation of this method:
    1. -(void) SetImage: (uiimage*) Image forkey: (nsstring*) Key {
    2. [_cache setobject:image Forkey:key];
    3. }
  Download a picture from the Web to add a dictionary, you will notice that these pictures have never been clear from the dictionary.   That's why memory keeps growing because applications don't delete things from the cache. It will only increase them all the time.   To resolve this issue, you need to imagecache receive a warning when uiapplication memory is tight. Clean up the cache.   To enable Imagecache to receive notifications, modify the Init method as follows: 
    1. -(ID) init {
    2. if (self = [Super init])) {
    3. _cache = [nsmutabledictionary new];
    4. [[Nsnotificationcenter Defaultcenter] addobserver:self selector: @selector (memorywarning:) Name: Uiapplicationdidreceivememorywarningnotification Object:nil];
    5. }
    6. return self;
    7. }
Register Uiapplicationdidreceivememorywarningnotification Execute memorywarning: method.
    1. -(void) memorywarning: (nsnotification*) Note {
    2. [_cache removeallobjects];
    3. }
Memorywarning deletes all objects in the cache. This will ensure that the image is not held. In order to test this fix, start the instrument again (with CMD in Xcode) and repeat the steps. Do not forget to end the memory warning in the simulation! Note: Make sure you exit from Xcode and rebuild instead of just clicking on the red button on the instrument to make sure you're using the latest code. This analysis should look like this: memory is severely degraded by memory warnings at this time. But there is still some memory overall growth, but not as much as it used to be. The reason is still a certain growth is due to the system library, and there is not much to do. It appears that the system library does not release all memory, which may be by design or may be an error. What you can do in your app is to release as much memory as possible and you've done it! Good job! There is also a problem, patched up,-there is still a leak and you haven't solved the first type of problem. Memory LeaksMemory leaks of the instrument. This is used to find the first class of leaks mentioned earlier-the kind that occurs when an object is no longer referenced. Detecting leaks is a very complicated thing to understand, but the leaking tool remembers all objects that have been allocated, and periodically scans each object to determine if there is anything that cannot be accessed from any other object. Turn off the instrument, go back to Xcode and choose Product->profile back to your app! Perform a search to get the results. Then click the Preview line of the result to open the full screen browser. Press the Rotate button in the upper-left corner, and then press again. Back to the instrument, wait a moment. If you have completed the above steps correctly, you will find that the leak has already appeared! Your tool window will look like this: return to the emulator and press the spin several times. Then return to the instrument and wait to get the following result: Where did the leak come from? The extended Details panel opens a list of Cgcontext on the extended details panel. Select one of the elements on the cgcontext in the list, which indicates that the object to be created, such as the following stack trace: Again, the frame that is involved in your code is displayed as black. Because there is only one, double-click it to see the code method. The problematic approach is rotatetapped: This is the handler that is invoked when the spin button is tapped. This method rotates the original image and creates a new image, as follows:
  1. -(void) rotatetapped: (ID) Sender {
  2. UIImage *currentimage = _imageview.image;
  3. Cgimageref currentcgimage = currentimage.cgimage;
  4. Cgsize originalsize = currentimage.size;
  5. Cgsize rotatedsize = Cgsizemake (Originalsize.height, originalsize.width);
  6. Cgcontextref context = Cgbitmapcontextcreate (NULL,
  7. Rotatedsize.width,
  8. Rotatedsize.height,
  9. Cgimagegetbitspercomponent (Currentcgimage),
  10. Cgimagegetbitsperpixel (currentcgimage) * Rotatedsize.width,
  11. Cgimagegetcolorspace (Currentcgimage),
  12. Cgimagegetbitmapinfo (Currentcgimage));
  13. CGCONTEXTTRANSLATECTM (context, rotatedsize.width, 0.0f);
  14. CGCONTEXTROTATECTM (context, m_pi_2);
  15. Cgcontextdrawimage (context, (CGRect) {. Origin=cgpointzero,. size=originalsize}, Currentcgimage);
  16. Cgimageref Newcgimage = cgbitmapcontextcreateimage (context);
  17. UIImage *newimage = [UIImage imagewithcgimage:newcgimage];
  18. Self.imageView.image = NewImage;
  19. }
Again, the instrument can only give you a hint here, where the problem is, it can't tell you the exact location of the leak. This is the only place where you can prove that you are creating an object leak. You may think that arc and there is no way to cause a memory leak in the code ... Right? Recall that arc only deals with Objective-c objects. It does not manage the release of reserved and Corefoundation objects instead of Objective-c objects. Ah, now it's starting to become obvious what's the problem? -cgcontextref and Cgimageref objects will never be released! To solve this problem, add the following two lines of code at the end of the Rotatetapped method:
    1. Cgimagerelease (Newcgimage);
    2. Cgcontextrelease (context);
Both of these calls need to maintain a count of the retention of both objects. This description, you also need to understand the reference count-even if you use the arc! in your project From Xcode, use the CMD tool to build and run the application. In the use of leak instruments then look at the application and see if the leaks are fixed. If you follow the above steps correctly, the leak should disappear! After language: Foreigner original Http://www.raywenderlich.com/23037/how-to-use-instruments-in-xcode

Use instruments for iOS tutorials to test your app

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.