Tools • iOS, OS X • 44:36
Xcode includes a powerful graphical debugger backed by the new, state-of-the-art LLDB debugging engine. Discover how you can detect and fix your performance problems earlier, configure advanced breakpoints, easily explore your variables within the editor, and take advantage of the new XPC debugging support built right into Xcode.
Speakers: Chris Friesen, Troy Koelling, Han-Ming Ong
Unlisted on Apple Developer site
Downloads from Apple
Transcript
This transcript has potential transcription errors. We are working on an improved version.
My name is Troy and I'm an engineer on the debugger UI team for Xcode. And I'm glad to see so many people here today because we all know that debugging is really important. And you know that debugging is what sets your app apart from the app on the App Store that gets one star because it crashes on launch.
And debugging is what sets your app apart from the app on our iOS devices that use all the memory and evict other apps when our users are trying to do some multitasking. And debugging is what sets your app apart from the apps on our Mac and iOS portables that use all of battery life in just a few hours making it a worst experience for everyone.
But you guys know that already. You're here because debugging is hard. I like this quote from Brian Kernighan and it says, "Everybody knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you're writing it in the first place, how are you ever going to debug it?" Well, the answer is better tools and specifically, the new debugging tools in Xcode 5.
We have a lot of new things to cover today. But first, let's go on a tour of the UI so we have a common vocabulary when we know-- when we're talking about these things. So here is the brand new, Xcode 5 UI. And the first thing you're going to notice is we've moved the breakpoints activation button from the toolbar down into the debug bar because it's right there next to the other tools that you need when you're debugging such as Continue, Step Over, Step Into.
And it's just a much more natural place to disable all your breakpoints if you need to do that and then hit Continue. If you need to enable or disable breakpoints one by one, of course, we go to the breakpoints navigator. And here you see a list of all of the breakpoints separated by filename and line number.
And you can edit or disable, enable breakpoints right here. But not all breakpoints have filenames and file numbers. There are some special breakpoints. And we create those down at the bottom of the window where you can create symbolic breakpoints or the exception breakpoints that are more special breakpoints. And we got a two new breakpoint types that are like the exception breakpoints. And that's the OpenGL ES error breakpoint and the unit test failure breakpoint.
Both of these breakpoints are kind of like the exception breakpoints where you can set it once and just kind of forget about it in your project. And then when you have an error, Xcode is going to pause in your applications code instead of some error handler later on. So that's a really great way to catch those errors in unit tests and in your OpenGL ES games on iOS.
Let's move on to the-- there's another navigator that's really important of course and that's the debug navigator. And the first thing you're going to notice in the debug navigator is this brand new debug gauges. And we're going to talk a lot about that later. So let's skip it for now.
I do want to draw your attention to this icon here. This is the spool of thread icon and this means that your debug navigator is in threads mode. And so, down here, you get a list of your threads and a stack trace where you're paused in the debugger.
And this is a really great place 'cause you can navigate through that stack trace and jump through the files that led up to where you are in your paused application code. And you can even check out the parameters that went into the calculations that got you to this point. And so, you can figure out why you got to this point and why maybe you need to go somewhere else.
But let's return back to that spool of thread icon because you can change that and a lot of people don't know that. If you're using grand central dispatch, it's more natural to organize your threads by cue. And so, this is exactly what this spool-- this grand central dispatch stoplight icon indicates that we're grouping your threads by cue. Now, let's move on to the variables view.
The variables view is where when you stopped at a breakpoint, it will show you the most important variables for that line of code and that might be local variables, it might be instance variables or parameters to the method and Xcode does a really great job of choosing those variables for you.
But in some situations, you need to find out a little bit more information. Maybe, you need to find out a global variable state, or you need to find out some register states. And so, you can click on this toggle down here and change auto to all and that will give you a more expansive view of your variables.
Let's move on to the debug console. The debug console is where you receive the output from your application whether that's NSLogs, printfs, or maybe the system frameworks that you're using are showing you some warnings or errors that you need to be aware of and they're going to come out right here.
Of course, when you're paused in the debugger, this is also where you have a direct conduit to the LLDB debugger which is a state of the art debugger that powers so many of the features in Xcode, and we're going to talk more about that and how it's integrated with Xcode more a little later.
And so, that's basically the main aspects of the debugging in Xcode. And of course, we've added new things which we're going to talk about today including the new debugging gauges which we saw briefly. We're going to see a new way to debug, a new debugging workflow. And then we're going to look at a specific debugging workflow which is really great now with XPC services.
So let's talk about performance. We all know that performance is extremely important. Nobody likes to see stutters in their application. Nobody wants to see scrolling stuff for any reason. But you've ever hung on the Apple developer forums, you may have heard, "Don't pre-optimize." And you may even get this quote from Donald Knuth that says, "Essentially, pre-optimization is the root of all evil." I think we can agree that there's a little bit of hyperbole here.
But we can also agree that if you think about performance before you think about code correctness, you end up with code that's harder to read, code that's harder to maintain, and ultimately, code that may not even be correct in the first place. So if performance is such an important aspect of your application, but we don't want to pre-optimize when are we supposed to optimize our programs? We should optimize when we measure a problem. This is the only time that we know what's going wrong so we can fix that instead of what we think might be going wrong.
And Instruments is the best place to go and optimize your code. There are sessions this week and there's videos from prior years to tell you how to use Instruments. But the good news is now in Xcode 5, Xcode is measuring for you all of the time, and that's the new debug gauges.
Debug gauges show up in the debug navigator, right there where you can always see them. And this is really great a place for them because when you just pause, it switches to that. It's right there, you just need to peak behind your current application or if you're on a device, it's right there on your Mac. There's a bunch of debugging gauges to show you the performance and the characteristics of all sorts of technologies.
There are two debugging gauges that are universal no matter what kind of app you're writing, what platform you're targeting, and that's the CPU and the memory debugging gauges. And so, since those are universal, we're going to take a look at them more closely today. So first step, the CPU gauge.
We show you a chart of the recent history of a CPU utilization which is your first indication that something may be going wrong in your application. If you see a spike that you didn't expect, or if you see a pegged on a processor and you don't know that that's happening, you want to take a look at that, take a deeper look. And to do that, you click on the CPU gauge and it brings up the beautiful CPU debugging report.
Some of the characteristics of these reports that are common among all of the reports, so let's take a look through some of the aspects. First we have this view here which is the meter view. The meter view shows you a snapshot of what's happening in your code right now in your application to give you an idea of what's going on right now.
As you can see here, we're using 97 percent of the CPU utilization. And that puts the needle about halfway because this iOS device has a two core processor and so, it's out of a total of 200 percent. We don't know whether that's 50 percent of each core and we don't know if that's 100 percent of 1 core, and zero percent of the other. But we know that approximately, half the CPU utilization is going to our application.
I also want to draw your attention to the small inner blue arc because that's a range of the last few minutes of CPU utilization. So you know whether things have been wildly swinging back and forth or if it's just been pegged at a narrow range such as it is here between about 60 and 100 percent.
The next area is the utilization across the whole system because all know that our applications do not run in isolation. Other applications affect how our application runs. And so here, you can see in purple that we are using about half of the total CPU utilization potential. The orange area is all the other applications which on iOS is very well-behaved. So it's a tiny little 15 percent slither.
And then of course, the free area is the gray area. And as we've been stressing all week, if you have work to do, you really do want to use all the CPU can and then let it go to sleep. Let the computer-- the machinery underneath your application go to rest for better performance and power.
Now, we have the main section of the report. This is where we have some graph showing you with history, basically, the history of that needle up above. And the first one is a large graph because that's showing an aggregate across all your threads at the CPU utilization over time.
Below that, we split it out by the threads. And here, we only have two threads. But these-- as your threads come and go, we will add or remove graphs down here. In this case, we can see that thread 1, the main thread is getting a lot of activity and whatever that second thread is basically doing nothing. So this might be a good opportunity to profile our application and see if we can move any of that off the main thread.
And of course, as I said, the best place to do that is in Instruments. So the most important part of this report is the Profile and Instruments button. And this will launch Instruments, open up the time profiler template, and gets you started down the path to fixing this problem.
Let's move on to the memory report. The memory gauge sets in the debugging navigator just like the CPU gauge and it shows you a chart of what's going on giving you a first indication that something maybe going wrong or maybe, an indication that everything is just fine. If we click on this gauge, we get the memory report.
And like the CPU report, it has similar sections and the first section is the meter view. The meter view in this case is showing 153 megabytes being used which is about a third of this iOS' devices total memory. It also has that inner blue arc which shows you the range and since I've been measuring quickly after the start of this application, the range goes from zero to where we are, 153, because hardly, any time is elapsed.
If we go over to the total system utilization area, we can again see in this pie charts that we're using about a third of the total system's memory. And that the other applications on the system are not using very much but you can imagine that other applications might be affecting our application. We might be getting memory warnings because of our app or other apps.
And finally, we have the main gauge area. And this is where you can see at a glance that something might be going wrong with this application because we seemed to be doing a repeatable set of steps and memory usage is just monotonously climbing up, and up, and up. And so, this would be a great opportunity to profile in Instruments or as my colleague, Han Ming [phonetic] is going to show in a real life example, how we can solve these problems by looking at these reports.
[ Applause ]
Thank you Troy. So I'd like to show you how to make use of the CPU and memory gauges to detect performance issues even while you're actively developing your application. So let's get to it.
[ Pause ]
So the app I'm using is a Mac application. But everything I say here today applies completely to your iOS apps. So to set the stage, imagine I have an award-winning application on the Mac App Store. People love it because it does one and one thing really well. It shows you exactly one picture.
Now because of this unsurpassed simplicity, it has been downloaded many times over the last couple of years. But my users are clamoring for more features. So in the next release, I'm adding two new features. The ability to add filters to the image and the ability to do rotation. Let's try them out.
[ Pause ]
So you can see, I have four filters. Let's try the rotation-- distortion, I'm sorry, sepia tone. I notice a little bit of a lag, maybe a tenth of a second, or a quarter of a second every time I change the filter. I'm going to assume that Apple has done an incredible job of optimizing those core image filters. So my next idea is to add a cache so that if my user reselects the same filter, it would be lightning fast. So I'm going to do that.
So this is where I create a cache, scrolling down, this is where after the cache, I'm going to put a breakpoint here so that when it breaks, I can validate that I have successfully added to the cache. And this is where I make use of it, I'm going to recompile and run so I hit the breakpoint, that C. I'm going to make use of our variable view, zooming in here. And oops, so one key value pair. So that's good. So remove breakpoint and continue.
Now, the debugger team would like you to build up a habit of whenever you add a new feature, a new enhancement to cleanse over to the debug gauges, just to make sure that now everything is behaving OK. So please keep your eyes peeled in this particular case to the CPU and the memory gauge while I try out my new cache.
With distortion, CPU is behaving pretty well. Memory went up a little bit because I just added a new filtered image. Sepia tone, same logic. Now, let's try out our new cache by reselecting back distortion. Oops, memory went up a little bit. Now, just to reconfirm what I saw, yup! So now, we don't want you to get paranoid over every single bump on the chart. But if you see a monotonous growth pattern like this, it should pick your interest. And it does for me. So I want to get more detail about it.
So I can do that like Troy said, I can select the gauge on the navigator and it will show me a report of it. The top section is a snapshot but what really jumps out at me is the graph. This pattern here. So something is definitely cuckoo here.
Now, I can select, I can click on the profile and instruments button to get more detail but sometimes, because this is your own source code, you have reached in for last couple of years. And I just added some more new lines so we can reflect on it and see what you just did. So let's look at that.
So here is where the cache is created, nothing is wrong here. Here is what I make use of it, seems-- looks OK. So this line right here, now, those of you with eagle eyes would have noticed that I've made the classic rookie mistake of confusing the key and the value. So, you know, obviously, that's not going to work. Even though when I've checked it early on, it was in the, you know, I added one key value. So let's switch them, switch the order.
[ Pause ]
I'm going to recompile and run. And I'm going to try them out again. Distortion, sepia tone, this is the important part. Let's go back to distortion. And you can see that we are staying at for about 39 megabytes. Let's try it again. So that the debug gauge, the memory gauge validates what I think is happening, the correctness of it. I just want to expand a little on what goes hand in hand with the memory gauge.
Some of you may have had used that usually involves a repeatable pattern, a repeatable user gesture. You know, you do X and then you do Y to make X go away. Sometimes, you have to do X again. A concrete example would be on the iOS, you put up a picture, you flick it away, then you flick it back. On your Mac, you may open a, you know, NSDocument-based document and then close it so you get the idea. So I'm pretty happy with the cache, let's move on to the slider.
[ Pause ]
All right, let's try it out. OK, it looks like it does what it says and now rotating. Again, I'm going to glance over to my CPU and memory gauge and try it out. So memory seems pretty stable, but there's something interesting about the CPU. You cannot see here but even after I've released the button, there seems to be some activities, CPU activity going on. Again, I'm interested in it.
So let's select it. The top section is the snapshot, the middle section is the utilization overtime which is the accumulation over the usage on the threats, and the last section at the bottom, the threat activities on each threat. You can see that, well, I know that when I did the rotation, I'm using set bounce rotation on NSView. And what's surprising for me is that I'm seeing activities on many threats.
So I'm going to leave the report right there and try out my slider again to see if I see anything interesting. So I can see that a whole slew of threats just came on. Now this-- that's weird too, you know, I'm and I think I just wrote the set Rotation method, I'm going to go back and take a look at it.
So here's where I noticed the rotation changes or I cut it down and I set a flag, this method right here. So when I wrote the method, it was necessary for me to call this method to get-- fill that image so that I can rotate it. This method that uses a dispatch cue so that work is done on a different threat; they'll by explaining why we saw a lot of activities on threats, but we have a better way now, we're keeping-- I'm keeping instance variable to filtered image.
So this method is not necessary, now I must have missed it in my refactoring early on. So let's get rid of it, recompile. And I'm going to bring up the report, scroll to the bottom, try the rotation again. And this time you see that, there are no new threats coming in. So I'm pretty happy with that as well.
CPU like what Troy says or what you have heard over the last few days. Now we want you to do use as much CPU as possible to get the work done in the shortest possible time, so that the rest of the course can go to rest, thereby saving you battery power.
So do not be afraid to make used of the CPU to get real work done. So that concludes about my demo and I have this one thing, I want you to take out from here is that, whenever you-- a new feature, a new enhancement and you're-- in the process of testing it, please remember to consult the performers, the debug edges to make sure you don't add any performance regressions to your application, thank you.
[ Applause ]
Thank you, Han Ming. As you can see these debugging reports give a great high level overview on what's going on in your application. But as debuggers, we-- they can't always rely on a high level overview. Sometimes, we need to go down deep, sometimes we need to look at the specific state of our application in a specific instance variables that make up our application. And so for that, I'd like to talk about the new data tips and Quick Look features.
If you're gone programming for a while, you know that you're getting into the cycle, you write a little bit a code, you hit run, and you do some debugging, and then you go back and do some more coding. And in Xcode, it's going to look like this. You have your big code editor and you're writing code.
And when you hit a breakpoint that debug area comes up showing you useful information. But a lot of times, we get all of the context we need from our code and so it would be great to be able to see the whole method that we're working on and just hide that debug area for when we really need it.
And so then, we'd have a debugging experience that looks more like this and so that's exactly what we have done in Xcode 5. The first thing we did was we improve data tips and how do we improve them, we strip away all the extraneous information. You already have the variable name there, I assumed you also know that this is a size variable, so you don't need the type and the name.
All you care about is the width and height of this size variable and so that's what we show you. But you'll notice we added two more things to this data tip. And the first one is the Info button and if you press that, you get the results as if you typeed in the LODB console, PO or print that object.
[applause] It's really handy because right there in your code, right where you need it, but we didn't stop there. Variables, even simple ones like size has visualization about them that you would like to see, maybe you want to see the aspect ratio. So you can click on this Quick Look button and see that size variable right there in the code in a visual representation. [applause] And this is super helpful. So to show you a demo of how this works in practice, I'd like to invite Christopher Friesen.
So our users loved the new features, the Han Ming about it. The filters are great, even my mom is sending motion blurred cap-- pictures already, so, you we know, that made a great success. Now there's another feature they want, you know, rectangular boarders around your pictures are, oh, they're pretty normal, but they're also kind of not that exciting. Our users want something little more edgy. So I've been working on another feature and let's take a look at that.
[ Pause ]
So we'll run our application here and I've added the Mask button down here. So this is creating a mask for the image which is-- what our users have asked for. However, what they really wanted is they want a star shape. So I'm in the middle of running this feature and I want to use the data steps in Quick Looks to figure out what's gone wrong with my implementation.
So I'll go back here and I'll use the button down here at the bottom of the Debug bar to activate our breakpoints and then we'll exercise our application to hit our breakpoint. So here we are, we're creating a Bezier path that will become our mask but we don't know exactly what's wrong with the shape. We can use our data tips to hover over it.
We can click the Info button to get a description of it. Well that's all the stroke information, I can breakout some graph paper and plotted out or I can click Quick Look. And here we get our wonderful image Bezier path that we're using to mask or image. That's not what we want.
Let's take a look at our method here. So our method is lazily initializing the Bezier path. So as you can see, since, we already have a mask, it's going to return out of this function. We can use our data tips to actually edit the value. I can double click on my address here, I can enter zero to nil that out. And now as we step over this code, we won't return out of the method early and we'll go, get into the code that's going to setup the Bezier path and we can start debugging that.
So I'll continue here and now we're on the for loop that's going to go through and it's going to construct the shape. Let's click continue about three times and then we'll see how our Bezier path is coming along. We can hover over any reference to mask in this method and we'll see what the current value is. Again, we'll use Quick Look and we can see that it's starting to draw the shape. Now in order to draw a star shape, we need the drawing points at alternating radiuses.
If you look at our radius, we see that every other time through the loop, it should be using a different radius. So let's look at R2. We see that's 200, R1 is 100. So they're both the same, so that's why we're not getting the shape that we wanted. Again, I can use data tips, double click on the value and turn new value and now that value has been changed in our running program. We'll continue several more times and then we'll check on the drawing.
Click on Quick Look and here we go. So we're starting to get our star shape, great. We figured out where the problem is. And we'll go ahead and continue. And here we are in a drawRect method. So it will-- we have completed our Bezier shape, our Bezier path and here we see the complete shape, and as we continue over in our application, we've got the distortion filters been applied as well as our mask. So we're nearly there. Now another thing you can do with the data tips is that you can go ahead and inspect the values, you can crawl in to the variables, and dive into them will say.
So let's set our breakpoint again, exercising our application, and we can hover over self for instance. And here we see that self doesn't have a nice concise summary so we show you the type as well as the address. So over here on the left, we can turn it open, we start seeing the instance variables and properties, and we can see the same for the super class. Here's a frame, again, Quick Looks are also available as you drill down into these variables.
Here's another URL. We can do a peel of it. Again, this is a textual description of what it is, not many people know, you know, can picture the latitude and longitude of that, but we can use our visual Quick Looks to see exactly where this is, we'll do that and here we are, we can zoom-in.
[applause] And it sure looks like it's near where we are and there might some event happening in the Yerba Buena Park. So that's data tips for you. They now provide concise data for you as well as these great visual data tips and we hope this will hope keep you in your source code as you do your debugging, thank you.
[ Applause ]
Thank you, Christopher. Now that showed a couple of a data types available and I'd like to run through some more. But let's talk a little bit about how this works because this is a developer conference and I trust you guys with the information about how these things are put together because it's really interesting. LODB powers, many of these simple ones like NSIs because it has data formatters that returns to us the within the height.
But we also support more complex types like images, we support UI image in iOS, NS image on Mac OS. But also CGImageRef and CIImage. And CGImageRef as you well know has a bunch of functions that get information out of it. So if we want to get a CGImageRef off your iOS device, in Xcode, we construct the expressions, and we send those using LODB to your running application and we say, CGImageGetWidth, we do the same with the height, and the color space, and even the bytes of the image that get shipped over the wire back to Xcode where we can reconstruct the image and show you right inside Xcode. And believe me that's much easier than any debugging method for seeing an in-progress image that you may have had to use in the past.
We also support NSString and we support NSAttributedString, so you can see your fonts and colors right inside Xcode, instead of the plain text view that might be in the console. And it's really great for long strings because it-- of course, it doesn't fit there in the data tip. So you can scroll through the whole string and see it large right up in your screen.
We support NSPoint, we support NSData, and this one is great because data has bytes and we format the bytes nicely, NSView. But data also has, as we all know, it often comes from files of streams and that's usually character data. And so right next to the bytes, we show what those bytes would be if they were ASCII characters.
And so you can see here that this is probably a Plist that's been loaded from disk. We support Core Location and if you know, Core Location, it's basically a pretty bare bones object that has latitude, longitude. And so recognizing what that latitude and longitude is, is very difficult unless you have the map right there in Xcode. So this is very powerful.
Similar to Core Location, we have, we support colors. And so, rather than looking at that triplet of RGB values plus alpha, we show you the color right there. We support Bezier paths, both on iOS and Mac OS as Christopher showed in his demo. And we support URLs. And it's important to realize that URLs have a path, that's a string representation, and we show you that in the data tip, but we also show you the contents of that URL because that's just as important to you who is trying to understand how your code is working.
So we'll render web pages from the internet and put those right there in Xcode or we'll load files from your local disk and show those as well. In this example, I'm running a program that has URL that's referencing a keynote document. In fact, it's this keynote document and I can see it right inside Xcode which is really powerful. And so Quick Look is a new powerful way to debug your applications that makes it a whole lot easier and a whole lot more fun to see what your value-- the values are.
Visualizing data type is not the only thing we need to visualize, especially, if like me, you work on UI things. And especially, in your Mac Apps because your windows have many, many views and you want to visualize, let's say the bounce of each view. And so when I would like to highlight is the Show View Frames which will put a colorful rec-- rectangle around every view in your application.
I actually used this recently because I had a toolbar which I needed to make a little bit smaller. And it has-- as you know, the toolbar will take the tallest toolbar item in it to represent the full height. And I had one icon that had invisible background that was bigger and I didn't know which one it was. So I turn on this option and it was easy to pinpoint exactly which toolbar item it was and I could change the, our asset, debug it, make that item smaller and fix my bug, it was green.
Now if you're on iOS, we also have some solutions for you. Many people don't realize that LODB accepts expressions which are fully qualified Objective-C statements. And so if you have a method, let's say the UIViews recursive description, you can send a message to that object, telling it to return the string for that recursive description and print it to the console. And this allows you to see what the child views of that view are. And many of the properties that you might need to debug what's going wrong with your UIViews.
And so these workflows are very powerful. And now I'd like to switch gears and talk about the specific debugging workflow that we've made really great and that's XPC Services. But first, let's talk a little bit about what XPC Services are. XPC Services are really powerful bits of functionality that you separate from your main code in order to have stability or maybe security.
And Xcode provides a template if you're writing a Mac App that will allow you to create one of these surfaces which makes a bundle inside your application which is a separate process that gets launched by the system when you call the APIs that call it up. And this bundle can be communicated too, you can ask request things from the bundle and when that operation is completed, it will send the message back with the results of that procedure.
This is possible to do in Xcode 4 to-- it is possible to modify your scheme to wait for these XPC services to come up. And when they do, your Xcode will attach to it. And what does that mean to attach to XPC Service? That means it gets its own entry in the debug navigator complete with its own gauges.
And if you said breakpoints in the XPC Service, they'll stop in those breakpoints just alongside your Mac Application breakpoints. So it's easy to be able to step through each of them concurrently just by switching back and forth between the process and the debug navigator. But the difficult part is that when this communication ends with your service, the system is allowed to wreak that XPC Service to free up system resources for other apps.
And so to make that even better, we've improved the situation in Xcode 5. When Xcode debugs your application, it starts listening for any services in your application bundle. And when those services come up, Xcode automatically attaches to it, meaning, you can set breakpoints, you can see it in the debug navigator, you can check out the CPU and memory reports for those.
And when it goes away, Xcode automatically detaches. But Xcode is waiting once again for that service to come back and we'll attach to it again, providing a seamless experience for you XPC Service debugging. This works great in practice and I'd like to invite Christopher Friesen up one more time to give a final demo.
So yet again our users want another feature. They want to be able to look at any image of the internet. Now this might be kind of dangerous to do. So we're going to put this functionality in an XPC Service so that it's partition from our main application. So we've changed the input to be a URL and we put this on our service. So let's take a look and see what Xcode does as we debug this application.
So I'll click the run here, our application starting up. Now we've hit a breakpoint where the main app is now setting up an XPC connection to talk to our service. You'll notice that in the debug navigator, we currently have just a single application. Our debug gauges and threads and stacks. Now as I continue, watch this area and you'll see that we automatically attached to the XPC process. And there it just showed up.
You'll note that it has a different icon in your main application. It's a black and white screwdriver and a wrench. And again, it has the same debug gauges and the same capabilities in this debug area. As you see in our application, we've fetched the image and we're displaying it. Now in order to debug in your XPC Service, you simply need to go set your breakpoints. So we'll go to our breakpoint that we've already created. I'll set it in our service and then I'll go back and exercise our application.
Here we are. It's now in the debug navigator, you can see that we've got our main application which is still running, the gauges are still whirling away, the UI is still responsive, but the XPC Service has been paused. And here you see that we're stopped in thread 16 on stack frame zero.
And we can continue our application. And we see that we've returned back from the service, applied the filter and display it in the UI. Now another thing to note is that the Stop button doesn't show that multiple processes are running. This is because we grouped them together so that whenever you click stop, we'll stop your main application as well as your-- any XPC processes that you have running, this is so that you can go back, change your source code and then next time you run, we'll use that-- those changes in your XPC Services. So let's watch that debug area as I click Stop.
I know, it's exciting when it just works. So there, so this is, so as we said, XPC debugging is automatic and enabled by default, but there's also a toggle for it. So let's go to the scheme popup and we'll choose edit scheme. Here we see that we're on the run action.
Currently, we have the info tab selected. If we go to the options tab, we see that the option to toggle our debugging XPC services is right here. So here, you can just toggle it on and off should you ever need to, most likely you won't. And we hope that the XPC integration in Xcode for debugging your XPC Services will entice you to look at the powerful XPC subsystem in Mac iOS X and add it to your application, thank you.
[ Applause ]
So today, we've talked about a lot of new things. We talked about the new debugging gauges and the associated debug reports. We talked about data tips and the improvements they allow access to Quick Looks which are also available in the variable view. We talked about some drawing diagnostics that you have access to. And we talked about XPC Services and the debug capabilities in Xcode.
I know many of you; perhaps all of you have new features or new applications that you're working on right now. And I really hope that you use the new features in Xcode, maybe you take a look at that debug gauge and see what your memory profile is like.
Maybe you look at the CPU, maybe use the new Quick Looks to solve the problem in your application because Xcode is trying really hard to make sure you ship great Apps and I hope that's what you get to do. We have, of course, if you have any questions after the conference, you can talk to Dave DeLong or visit the developer forums. There are some really great people there. I've referenced some related sessions. Thank you very much for attending Debugging in Xcode 5, have a great week.
[ Applause ]