Video hosted by Apple at devstreaming-cdn.apple.com

Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2011-300
$eventId
ID of event: wwdc2011
$eventContentId
ID of session without event part: 300
$eventShortId
Shortened ID of event: wwdc11
$year
Year of session: 2011
$extension
Extension of original filename: m4v
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2011] [Session 300] Developer T...

WWDC11 • Session 300

Developer Tools Kickoff

Developer Tools • iOS, OS X • 1:09:03

Xcode is the development environment for creating great applications for Mac, iPhone, and iPad. Discover amazing new features in Xcode, and learn how to get the most out of your development experience. A must-attend session for all developers.

Speakers: Max Drukman, Matt Firlik, Jon Hess, Chris Lattner, Andreas Wendker

Unlisted on Apple Developer site

Downloads from Apple

HD Video (1.91 GB)

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Good afternoon. Welcome to the Developer Tools Kickoff. As you all know, our iOS and Mac platforms are growing like crazy. Apple has now sold hundreds of millions of iPhones, iPads, and Macs, which all have access to the app stores. There's a lot of users out there ready to buy your apps.

And so our app stores continue to grow beyond anybody's expectations. As you heard this morning, users around the world have now downloaded more than 14 billion applications. And all of them are built with one set of tools, and that's Xcode. Just a few months ago, we shipped our most ambitious tools release to date, Xcode 4. Xcode 4 has a user interface that was redesigned from the ground up. Most of you are probably familiar with it by now.

The new Xcode is built around a single window workflow. You can see several of its highlights here on the screen. The integrated interface builder right into the IDE. And our assistant editor split the window to automatically bring up relevant related content next to the file you're editing, so you can work on them side by side.

For example, when you're drawing a connection right from your GUI to your source code. Similarly, the version editor allows you to browse the revision history of your subversion and Git repositories, and view the changes you made in the side-by-side div view. You can even use the timeline in the middle to simply browse back in time on your project.

The new user interface is the most visible aspect of Xcode 4, but we also delivered major new versions of our low-level tool chain, with the compiler, debugger, and the performance tools. Version 2 of our LLVM compiler added full support for C++. And in general, we integrated LLVM much more tightly into the IDE, so that LLVM technology is now the basis for many features, like automatically improved code completion and syntax coloring.

Integrating LLVM into the IDE also allowed us to implement features like Fixit, which uses LLVM to check for and automatically correct coding errors right while you type in the source editor. And these are just eight of the many features you find in Xcode 4. It's a very big release, and it's really taking our tools to the next level.

In addition to making it available to you for download on the web, we are also offering Xcode Now in the Mac App Store, which is the easiest way to install the tools and to stay up to date on the latest SDKs. And we want to make this App Store experience even better for you going forward. We are working on a number of mechanisms to reduce the download size of the Xcode installer.

We hear you. By breaking it up into multiple packages, which you can download on demand only if you actually need them. And also, when Lion ships to end users in just a few weeks, Xcode is going to be free for all Lion users right from the App Store.

Now in the near future, we're going to ship two new tools releases to you. And we're going to time them with the operating system launches Apple is planning next few weeks and months. Xcode 4.1 will coincide with Mac OS X Lion, and later this year, Xcode 4.2 will add support for iOS 5.

Let's take a look at two of the features of these new tools releases, starting with Xcode 4.1 for Lion. The first thing you will notice is that we are making Xcode look great online. And take advantage of the many improvements in the new look and feel. For example, the new single window workflow in Xcode works fantastic in full screen.

Another thing you will see us doing more and more going forward is focus on keeping our platforms consistent and very integrated, and avoiding any kind of unnecessary fragmentation. And so it's critical that you take advantage of our latest technologies, tools, and SDKs. And to help you with that, we're introducing a new project modernization workflow, which will offer to update your projects to the latest settings that we consider the best practices. For the more performance-oriented engineers among you, we are adding the ability to view the compiler assembly and preprocessor output right in the IDE.

But the majority of new features in Xcode 4.1 will focus on supporting new line technologies and making the Xcode UI even easier to navigate. We're going to add support for the new Cocoa controls, like popovers and view-based table views, an example of which you see here on the screen. We're going to allow configuring Mac push notifications. And Xcode is going to get an editor to manage entitlements for sandboxing your apps.

We're also adding new customizable behaviors to Xcode. But most importantly, the integrated interface builder is going to gain support for the new Cocoa order layout mechanism, which allows you to define the resizing behavior of your windows in a much better way than springs and struts allowed you to so far. To tell you more about that, I'm going to head over to Max Drukman for a few minutes.

Thank you, Andreas. Good afternoon, WWDC. So since Craig already gave my demo, what do you want to talk about? Now, ever wish you had one of these? Yes, this is the mythical "do what I mean" button. Right, we've wanted one of these for years and years. Auto Layout is a little bit like getting a "do what I mean" button that comes already pressed. Let me show you.

So here's an image editing app I'm working on. This is the intro screen where my users can select folders of images for processing. I'm going to add one last button. I'm going to call it "Choose Another Folder." and I'm going to place it right where the handy Aqua guides tell me it should go.

Now, I'll wire that up later, but for now, I'm interested in seeing how my interface responds to resizing. So I'm going to run it. Now, judging from the applause when Craig mentioned this feature, I'm guessing some of you know what's going to happen when I resize this window. Let's have a look. Yeah.

That doesn't look right, does it? I have a couple problems here. One is that my whole interface is pretty much left in the upper left corner of my window. And I'm even getting strings truncating because I didn't allot for the number of digits I'm getting. I wish I had a do what I mean button. Let's see if Auto Layout can help. I'm going to start by simply enabling it. I'm going to go to the file inspector, and click Use Auto Layout. No other changes. Let's run and see what happens.

All right, any guesses now? Hey, how about that? Now, how does Auto Layout do what I mean? As Craig mentioned, thank you Craig, what Auto Layout does is it starts by taking the Aqua Layout guides and it makes them stick. So when I lay out a button in the lower right-hand corner of my window along the Aqua guides, it stays there.

It also looks at the contents of controls, for instance, the text in my labels, and makes the controls big enough to accommodate the contents, which is why I'm not getting truncation anymore. Now, there can be ambiguous cases, and I think I've got one right here. Yep, there's another classic case where I have controls that are overlapping. Now, for that, I would need the Read My Mind button. Unfortunately, I can't comment on future product directions.

Auto Layout has me covered here too. Let's have a look in Xcode. Now when I select the cancel button, you'll see that there are some blue guides that draw persistently. Those guides represent constraints. Constraints are objects that Auto Layout creates to keep the components of my interface aligned and sized properly. Constraints are objects you can work with just like any other object in interface builder. You can set outlets on them, even animate them at runtime.

Now there are a couple of interesting constraints going on here. The cancel button has a constraint that keeps it the default awkward distance from the open button. It will always be there because that constraint is there. It also has constraints keeping the baseline of its text aligned with the baseline of the text of the adjacent buttons. So those will always be vertically aligned as well. Now, the problem I had was the cancel button and the choose another folder button.

were overlapping when my window got too small. Now, the old school way of fixing that would be just bump up the width of my window, right? And I'm done. But I want my interfaces to look great full screen on a 27-inch iMac, not taking up all of the pixels on an 11-inch MacBook Air, and everything in between. So the right way to do this is by adding a constraint.

I'll do that using the editor menu, and I'm going to add a horizontal spacing constraint. Constraints can be inspected in the attributes inspector, and they can be set to be a fixed value or to be flexible. And that's what I'm going to do here. So I'm going to set this constraint to be greater than or equal to this value. And what that means is that when my window gets bigger, the constraint will allow the window to flex out. But when it hits that value, it'll stop.

Let's see if I'm right. So now, here's my window. I set one constraint, and yep, sure enough, Pretty cool. I now can't make this window small enough to impact these controls. That's because the constraints are working from the inside out to tell the window what size it needs to be.

Let's look at a more complex case. Once my users have selected an image to work on, they can use this interface to perform color filtering. So above is a preview of my image, and below are three boxes, each of which has some filter controls in it. I've already set up some constraints. Let me show them to you.

So when I select this label, there's a horizontal-- sorry. I knew I was going to get this wrong. There is a horizontal centering constraint. And what that does is it keeps the label always centered in the box. There are also two constraints, one on either side of the label, that work just like in my previous example as flexible space. They allow the box to get bigger, but only get small to a point. so it doesn't affect the label.

Now, I also have, all three of these boxes are set up the same way, by the way. And I also have a constraint between each of these boxes, and that is an equal widths constraint. What that does is it tells each of these boxes that they always have to be the same width, so that when my window resizes, all three of these boxes will resize the same way. This kind of multi-column layout used to be pretty hard to do and required custom code. Now, with Auto Layout, you can do it right in IB, zero code.

Now, why do it this way? Why are constraints a better way to do this? Well, If you think globally, right, when my app gets localized into German, it should still work. When it gets localized into Georgian, it should still work. And keep working. Because constraints are always keeping my interface doing the right thing. That's Auto Layout.

Let's look at some code. Now, I don't know about you, but I'm a little particular about how I want things to be when I'm doing code. So I'm going to do a layout of a different kind. I'm going to layout Xcode using full-screen assistant. Now, full-screen assistant isn't a new feature in Xcode, but it takes advantage of an enhanced feature in Xcode 4.1. We took the behaviors mechanism of Xcode, and now we allow you to make your own. Let's have a look.

Now, behaviors are a very powerful system that Xcode uses to perform certain actions based on certain triggers. For instance, when my app builds, I get a bezel alert that tells me that it succeeded. That's controlled by this behavior. As I said, in Xcode 4.1, I can now make my own. I can even assign keyboard shortcuts to them. Now, the full slate of actions are available for custom behaviors, just as they are for the behaviors that come with Xcode.

So, in this case, what I did was I told Xcode that I wanted to show a tab that I named. I want to hide the debugger, the utilities, the navigator, if they were showing, and enter full screen, where Xcode's single window plus tabs interface really shines. Now I can even do things like add custom scripts to do all kinds of interesting things. I could take over the world, assuming I can write a script that does that.

Now, there's one more kind of layout I want to talk about, and that is the layout of my code. So now we're talking about the compiler. So another advancement we put into Xcode 4.1 is the generated output category in the assistant. So now I can look at assembly side by side with my code. It gets generated on the fly.

If I want to, I can navigate through my project and see the assembly of any file I land on. I can even add another assistant. And, heck, look at the pre-processed output. Why not, right? So now, it's just my interface laid out, Xcode laid out, my code laid out. It's my moment of zen. Back to you, Andreas.

Thank you, Max. So that was an overview of the Lion-focused features in Xcode 4.1. Let's now take a look at what we have in store for you with iOS 5 and Xcode 4.2. First, we're going to add a number of features that will help you test and analyze what's going on in your applications.

You can now sync data from your applications back and forth between your test devices and your development Mac. And that behavior is even integrated with unit tests, so that you can now configure unit tests to run the specific data sets uploaded to your devices before your tests launch.

Instruments also adds amazing new capabilities. This includes system trace for iOS, a very commonly requested feature. Vastly improved multi-core analysis, so you can take better advantage of our dual-core processors. And a new network activity instrumentation that helps you identify situations where you constantly trigger data in and out of an app, which can burn through battery life rather quickly. Next, you can now simulate locations.

You can even record paths of locations and, for example, simulate the user driving around a specific street. or you can visit other countries and international locations. And all of that, of course, means that you can now make sure that your applications even work in places that you would never want to visit in person.

The next is a feature that will help you design your applications in a whole new way. How many of you have ever started designing an app on a napkin or a sketch pad like this shown here? So this is actually a great way to get your thoughts out on paper. It's not always easy to translate it to an app, and you can't put napkins under source control.

But this is really a great way to-- this way of-- sorry. This approach of designing application with multiple screens and transitions in between is actually very compelling. And we're going to realize it with a new feature that we call storyboarding. Storyboards-- So storyboards give you a view of your entire application. They get you up and running very quickly. To tell you more about this, I'm going to ask Jon Hess for a few minutes.

Thanks, Andreas. Storyboards are all about letting you build applications the way that you think about your applications. You get to see all of the screens that make up your program in one place. And more importantly, you get to see all of the paths that the user can take to navigate between those screens, all in Xcode.

We do this by introducing two new simple concepts, scenes and segues. Scenes are the major visual components of a storyboard. Each one is defined by a view controller and its associated view. Now, everything you already know about using Interface Builder, like using the inspectors, actions and outlets, all of that applies to building your scenes in your storyboard. And no matter how many scenes you put into one of your storyboards, at build time, we're going to process it and optimize it into a form where it can be loaded one piece at a time at runtime.

Now, this gives you great performance, but it also means that you're going to be able to build a lot of things in one place. And that means that each one of the scenes in your storyboard is actually more like a recipe or a template and can be instantiated independently multiple times. This opens up some really powerful workflows and sophisticated applications.

In addition to scenes, we also have segues. Segues are the glue that binds a storyboard together. Each segue defines how one view controller instantiates and presents another. Creating a segue in Interface Builder is easy. You just control drag from any event source, like a button, table cell, or even a gesture recognizer, to some other scene. And when you do this, you get to define a transition style that accompanies the scene.

We have support for all the system transition styles built right into Interface Builder, including popovers. You can even build your own custom segues. Storyboards apply to all sorts of applications, but today I'd like to demonstrate them to you by building the introduction to the OpenGL game you see behind me here, Touch Fighter 2. Let's go over to the demo machines.

We're going to get started with a new instance of the OpenGL game template. Our game will be Touch Fighter 2. We're going to target the iPhone, and we're going to use storyboards. Storyboards are the default with all of our project templates in Xcode 4. Now, Touch Fighter is going to be a landscape-based game, so I'm going to opt out of portrait by just toggling this portrait button here. And I have a little bit of prepared content in the doc that we're going to use today. Let me just drag that into my project.

So this is just a couple of images that we're going to use in the storyboard today, and one view controller to explicitly support landscape. With that, I'm ready to focus on my storyboard. I've got a new behavior that I've set up to jump straight into full screen and hide my navigator and show my utilities in my library.

Now, when I like to get started with a storyboard, I like to think about the application from the outside in. I like to think, what are the major view controllers or scenes that the developer or the user is going to interact with when they use my program? I'd like to put them all in first, and then build them and link them together.

I can get an overview of my storyboard by just double-clicking anywhere in the background to get a zoomed-out, high-level view. And from the object library here, I'm going to search for "view controller." and create two new scenes. This will be our main intro screen. The user will be able to choose a multiplayer level in one direction, or jump straight into the game for either single player or multiplayer. I can double click to zoom back in, and I'm ready to start building my scenes. In the media library, I've got a couple of resources that I'd like to use with each one of my screens. Here's a backdrop for our intro.

We've got a great star field for the multiplayer level selection. And as easy as storyboarding is, making an OpenGL game is still really rewarding. So I'm just going to use a screenshot here from my OpenGL game, and we'll leave that to all of you later. We have our three scenes basically laid out, and now we're ready to build some segues here so the user can navigate between them. I need an event source.

I'm going to start with a button and drag it over into our intro screen. And this is going to be the single player button to jump straight into the game. And I'll duplicate it once for multiplayer. Now, I'd like to customize the look of these buttons so they look great on my backdrop. I've got some custom images here. And I'll set some titles.

So, Now, I'd like that text to have high contrast, so over here in the inspector, I'm going to choose a bright orange and bump the font way up so it's easy to read. Okay, creating our first segue is as easy as control-dragging from the single player button to the other scene and letting go.

So here's our segue. This is a modal segue that's going to do the default transition. I'd actually like to be explicit and choose cross dissolve. I think cross dissolve is a quick, tasteful way to get the user quickly into the game. Okay. In our multiplayer screen, we're going to have two buttons as well to pick between two different levels.

I've also got some custom resources here in the library to make those buttons look great. We have an Andromedan Assault Level and Defend Earth. I'm going to make some room and create two more segues from those buttons into the game. Now we're ready for our final segue. We'd like the user to be able to click the multiplayer button here and jump to the multiplayer screen. But I'd like the user to be able to back out of this transition.

Should they choose that they want to go back and play a single player game. And perhaps the most recognizable way to do that in an iOS application is with the navigation controller. The navigation controller gives users the ability to quickly move back and forward on a list or a tree in an application.

I can create a navigation controller in my storyboard by just selecting one of my scenes, going to the editor menu and choosing embed in navigation controller. And interface will slide everything down to make room and create a new navigation controller for me. I'm going to select my navigation bar. Change this tint color to this dark brown that matches my screen better. And move my background picture to accommodate for it. Now we're ready to connect our last segue.

Okay, something interesting happened here. This brown navigation bar propagated onto this new screen. And if I look at the segue, it has a different icon than the others. This is a navigation push segue, and it's going to do a transition that slides in from right to left. Interface Builder could tell from the context of my storyboard with that navigation controller back there, that that was the best transition to pick by default.

You'll see if we scroll over to the Touch Fighter game, it doesn't include the navigation bar. That's because these are modal segues. And the modal segues are basically context-free, and they're not going to bring that navigation bar with them. I'm going to adjust these images to consider that bar, and I can set a title here.

and I can zoom out to get an overview and make sure that everything looks just the way I intended it to. I'm going to select all three of these view controllers. and opt them into that custom class I mentioned earlier that support landscape, and we're ready to run on the iPhone simulator. Here's our Touch Fighter 2 game. The user can click multiplayer, see the multiplayer levels. The navigation controllers provided this helpful back button. And I can jump straight into the game. Thank you very much. Back to you, Andreas.

Thank you, Jon. So since Jon already started building a game for us, let's take a look at what we can do to help you with the actual OpenGL part of it. There are more and more applications that leverage the powerful GPUs in our hardware through the use of OpenGL APIs. One issue with running OpenGL code is that it creates very different debugging needs in comparison to running code on the CPU. Back in March with Xcode 4, we started adding a number of tools that help you understand and diagnose OpenGL applications.

The first, very easy to use one, is the OpenGL ES Performance Detective, which is essentially an assistant that performs a number of experiments on your apps, and then tells you which stages of the OpenGL pipeline are the top suspects for performance bottlenecks. The Performance Detective can be used as a standalone application, but it's also integrated with Xcode exactly like Instruments is. So you can define profiling actions in your project schemes that invoke the Performance Detective right out of Xcode.

The other tool we added back in March is the OpenGL ES Analyzer instrument, which data mines the OpenGL command stream to collect per frame statistics, such as the number of patterns and OpenGL commands. And you can then easily view which commands account for the most processing time, and get specific recommendations for how to optimize your code.

Both the Performance Detective and the Analyzer Instrument are invaluable tools to better understanding and optimizing our OpenGL apps. With iOS 5, we're going to take it a huge step further. We're going to add a fully-featured OpenGL frame debugger, integrated into the IDE, which allows you to visually debug your applications and quickly zero in on drawing issues and rendering artifacts. To tell you more about this, I'm going to hand over to Matt Firlik.

Thank you, Andreas. When we first started designing the OpenGL ES debugger for Xcode, we had two main goals. The first was to dramatically simplify the debugging experience for OpenGL. We want the IDE to manage the complexity for you and make it really easy for you to find and fix issues in your OpenGL code.

Our second goal was to design a user experience for the debugger that was truly befitting the underlying technology. OpenGL being inherently visual, we wanted a dynamic and fluid workflow that was both powerful and intuitive to use. I'm proud to say that's exactly what we accomplished, because this is the new OpenGL ES debugger in Xcode.

The OpenGL ES debugger in Xcode starts from the foundation of the performance detective, the ability to capture a frame of your running application. We enhanced it with information about your project, your resources, and your source code, and then integrated it seamlessly into the Xcode debugging experience. The OpenGL ES debugger gives you access to a fully rendered frame of your application.

As part of that, you have access to all the draw and state calls that make up your frame, and all the resources that contribute to it. All the textures, the shaders, and the programs. And you also have full stack backtraces, so you can seamlessly move from the code you've written to what's rendered on screen and back.

and David We've added two OpenGL ES extensions to allow you to take concepts from your application and surface them directly in the debugging experience. The first is the ability to label your OpenGL resources. So in addition to referring to them by index number, you can also refer to them by a meaningful name like moon surface.

The second is the ability to annotate the OpenGLS stream with markers. Now these markers give you the ability to take a set of draw and state calls, and service them in the debugger by the concept that they impart to your frame. So things like planet, enemy fighter, explosion, or mother-in-law. So I'd love to give you a demonstration now of the OpenGL ES debugger in Xcode, and show you how it can maybe save the world.

So we're going to transition over here to the Touch Fighter application. What you'll be seeing on screen here is, this is the Touch Fighter application Jon started on with his storyboard. I had the rewarding task of implementing the OpenGL game. So you'll see that when I click single player, we've now transitioned into our game. And it's running here on our iPad. I can fire some lasers here.

Now this is your kind of standard space-faring application. You are the last line of defense for an unsuspecting planet kind of thing. And you can see that as we look at the different elements, there's the planet in the foreground, the mothership in the background, and then some enemy fighters in my ship.

Now looking at the screen here, we can actually see a problem right out of the gate, which is the upper two wings for my ship are drawn in black. I'm actually expecting those to have the same texture as the lower wing. So there's clearly a problem for us to solve.

Let's see how we can use Xcode to find and fix this issue. So let's transition over to looking at our Xcode project. And here we see the Xcode project for the Touch Fighter application. I need to clarify that what you're seeing here is a feature of modern projector technology. So this is the iPad projected picture in picture on top of Xcode.

Come on, it's going to get better. So here we are in our Xcode project. Now if I were going to debug this normally, what I would probably do is seek out the class for my spaceship, which I have here, and then find the method that starts rendering it and just put a break point. So we'll do that here. And you'll see that Xcode seamlessly transitions into the debugger.

And now I'm seeing the stackback trace, and I can use the standard debugging affordances to get information about how my program is working. But for something like OpenGL, I really want more context. I want the full view of what's going on. And looking at it as a single moment in time isn't really very helpful. So let's transition into using the full Xcode OpenGL ES debugger.

I'm going to remove my breakpoint and continue. And to start using the OpenGL ES debugger, we first need to capture a frame of our running application. To do that, I'm going to use a new button that's down here in the debug bar to capture a frame. It's a little camera icon. And you'll see that I'm going to click this button here, and Xcode's going to transition into taking a capture, and then bring that content directly into the debugger. So here we are. This is our OpenGL frame inside of the debugger.

Now, the debug navigator has switched to showing us information about our frame. All of the state, draw, and marker calls. And the editor is now showing us the rendered view of the frame at a moment in time. Now, it's showing me actually the last view of my frame.

But I can select any earlier point in the debug navigator, like Skybox here, and we'll transition to an earlier point. Now, I selected on Skybox over here, and it's one of these yellow folders. That's one of the markers I mentioned before. I've gone through and annotated the TouchFighter application with markers to delineate all the elements that contribute to my frame. Now, in addition to making it really easy for me to select one, it actually shows me a high-level overview of how my frame is constructed.

If I select the next element, stars, you'll see that we actually transition to showing the stars in the editor. Now, the green wireframe here is actually highlighting the elements that are drawn just at this moment in time. I can use the context menu and hide the wireframe if we wanted to see the direct details.

Moving along, if I take the planet section here in the debug navigator and expand it, you'll see there are a number of elements that contribute to drawing the planet. The blue cubes are the state calls. These are the things that set up when I'm about to draw. And the little spheres are the actual draw calls, the ones that take the images and actually put them on screen. If I select this first draw call here, we'll see that the view updates to show us the planet.

If I want to see more information about the state, about what's going on before I draw, I can do so by revealing the familiar affordance of the debug area. So the debug area here at the bottom has transitioned from showing us information about variables and registers to now showing us information about our OpenGL state. Both the global state of the whole context and those for just the bound objects. Those are contributing just to this moment in time.

We use the familiar affordance of highlighting elements in blue as they change. So for those of you who are sitting close enough, you'll see as I start to move through the debug navigator here, those items will highlight. Here we're turning off culling, which we use to draw the planet. I've bound up a new texture for the planet glow that we're going to draw. We're going to enable blending, and we set up a particular function to do that. And then when I get all the way down to the planet glow, it's going to draw on screen.

So I can see exactly how that happened. I can also show the wireframe so you can see exactly how the planet was drawn-- or the halo, rather. Or I can switch back to the planet, and you can see how that was drawn, too. If I want to go one level of detail further, I can also just disclose the item here in the Navigator and get the full stack backtrace. So I can jump right to the source code that put this item on screen. So in one quick view that's very familiar with the debugging experience, I've accessed a lot of information about my GL frame.

The flexibility of the Xcode workflow allows me to change how I'm working depending on what I want to focus on. For example, I can go up here in the toolbar and collapse the navigator completely if I want to focus on the main view up top. Actually, the view up at the top is showing me the buffer view. In this case, it's showing me the color buffer. I can actually enable other buffers, for example, seeing the depth view, or actually the stencil view, too, if I was using it.

Even in this layout, I can use all the familiar Xcode affordances to move about my frame. For example, I'm going to grab up here on the jump bar, and you see that it lists all the different elements in my frame. And I could select, for example, enemies and jump right to that section. Again, this is a value of the markers, allowing me to pick exactly the thing I want to see. You'll see that when I select it, we jump right to where the enemies are being drawn.

Now, when I think about my OpenGL frame, it's kind of like video, where you kind of want to scrub through it to get to the exact point you're looking for. And we've included a control exactly for that. There's a scrubbing control down here in the debug bar with the rest of the controls that you'll see as I grab it and move it about, that the frame will actually update to show me each point in time that I'm at.

And the green wireframe shows me the highlight of what's being drawn at that point in time, making it really easy for me to move all throughout my frame, for example, as my fighter is being drawn here, all the way to the end. So the scrubbing control makes it really easy for me to move about my frame.

Now, let's get back to the problem at hand here. We see our spaceship here, and the wings are still drawn black. Now, the wings are actually being drawn, so I know I've done some things right. The first thing I'd want to inspect is maybe I've not set up my texture correctly. I'm not using it to draw the upper wings. Now, to do that, I want to see more information about my frame, and I'm going to leverage the Xcode Assistant to do so.

I'm going to focus back on just the color buffer here. And you'll see as I enable the Xcode Assistant in the toolbar, the editor splits and now shows me information about the current frame and about the resources. In this case, the Assistant is showing me the bound resources. Those are contributing at this moment in time.

I could change the Assistant to show other content by selecting a different category. For example, here's the All Objects category. So these are all the resources that contribute anywhere throughout my frame, making it really easy for me to get a high-level overview of what I'm using. I can double click on any item to get more details. For example, here's the texture that's being used to draw the space background. Here's the texture that's being used to draw the planet that we see below. And I can even look at information like shaders and programs to inspect how they're affecting my frame.

If we go back here, and we'll take a look at the texture that's being used to draw my spaceship. I've selected it here. I can actually use the controls down at the bottom of the editor here to help me get a different view. We'll rotate this around a little bit to see better. And if I had multiple representations of this image, a technique called mipmaps, I could pick the different level here, but I only have one.

Now, this item up here, this dark gray wing, is the one I expect to be drawn. So I at least know from here that I've got my texture set up correctly. Maybe I've not bounded up correctly. So let's go back to the bound objects category in the Assistant and see how this can help me.

Because the Assistant Editor shows you content that's related to what you're looking at in the primary editor, and we know that this editor shows us moments in time, you'll see that as I use the familiar controls to step backwards, in this case, through my frame, that the bound objects actually update to show me what I'm using at this time.

Now you'll see the 60, which is the frames per second. As I step back, we now have the texture that's being used to draw the explosion, the one that's being used to draw the afterburner, and now I'm into the segment drawing the wing. So just like this, I can actually get a really quick view of how my frame is being set up and what I'm using.

Now, as you see here, as I click back through the parts that's drawing my wing, we actually do see my texture bound correctly up here. So I have set it up correctly there, but it's still not drawing. Something else is not going right. So I need to investigate further. The next thing I would probably check is, am I using my texture correctly? So to look at that, I'm going to expand the state view down here, and look at the details for my texture. And I can actually see the problem.

As I'm looking at the details for my texture, I see that I've bound up a filter that's expecting to use mipmaps, those multiple representations I mentioned before. In this case, I know I'm not using those, and my textures don't actually have them, so that's why it's drawing in black. So somewhere in source code, I've not set this up correctly.

The OpenGL ES debugger can actually show us the line of source code that caused this problem. And to do so, I'm going to add another assistant editor by clicking the check the plus sign up here in the editor. And I'll make myself some more room. Now, in this case, instead of looking at resources, I'm going to change the category to stack.

And now we see that right here, this is the line of source code that actually drew the element on the screen. So in one full view, we have what's on the screen, the resources being used, the state that it's in, and the code that's causing it. And of course, like you'd expect from a debugger, as I step through, it's showing me all of these items in concert.

So we can see when we get to this moment in time, the filter is now blue, which says that it's been changed. And sure enough, here's the line of source code that caused the problem. This really should be GL linear. And once I save that, that should fix my problem. So very quickly with the Open GLS debugger, I was able to jump into my application, find the spot I was looking for, investigate resources, state, and source code, and find and fix my issue. It's just that simple.

As an engineer, it's really gratifying when you can find the source of your issue. As a manager, you like to hold celebration until you're sure it works. So, what we're going to do here is stop our running application, and let's relaunch it to make sure that we actually fix the problem.

Now, we worked really hard to make sure that the OpenGL ES debugging experience just felt like the regular debugger. Like, there was no special magic. The first time I did a capture, I clicked the Manulate button in the debug bar. What I want to show you is another trick to allow you to get this capture a little bit easier. To do that, I'm going to add the breakpoint back that I've created initially. And in this case, I'm going to edit it. I'll bring up the editor with the context menu. And now this is the breakpoint editor.

Now, this argument here, time to this function, is actually the overall time elapsed in the game. So I'm going to set a condition here that says time is greater than four. So after four seconds, this breakpoint is going to get hit. And when it does, I want it to trigger an action. And in this case, I want it to capture an OpenGL frame.

So now you'll see that as I click the single player button here on my iPad, that the game is going to play. And after four seconds, I trust it enough to walk away, you'll see that the capture is going to start. Xcode is going to capture a frame. And sure enough, we fixed our problem.

So that's the OpenGL ES Debugger in Xcode. I hope you guys enjoy using it. Back to you, Andreas. Thank you, Matt, for showing us the OpenGL debugger. Let me now also give you an overview of our CPU debuggers. Last year here at the conference, we announced our new low-level debugger, LLDB. This is a brand new debugging infrastructure that, just like our compiler, LLVM, is designed with a strong focus on performance and the ability to integrate it well into the IDE.

In Xcode 4 in March, we already made LLDB available as a debugger for Mac applications. In our next release of Xcode, we're going to add support for iOS as well. So you can now debug your iOS applications, whether you're running natively on the device or in the simulator. LLDB is the future of our debugging technology. It's going to replace GDB in the not-too-distant future. And we'd actually love to hear what your experience with it is.

Now, LLDB is also an open source project that we publish under the LLDM umbrella. And that finally brings me to our compiler story. Until several years ago, we relied on GCC as our compiler for both the Mac and the iOS platforms. But today, our compiler of choice is, of course, LLVM. And with iOS 5, we're preparing the next major release of it, our LLVM compiler version 3.

LLVM is designed for speed, flexibility, and modularity. It compiles code about twice as fast as GCC. And at the same time, it creates better and faster code. LLVM is also the compiler that's integrated into the IDE for features like Fixit. and LLVM is the only compiler in which we implement support for new language features we are developing, like C++ or X.

So LLVM and the rest of the team. And now, let's talk about the next step. LLVM is now a very mature and proven compiler. We've actually switched all our internal products over to building with LLVM. That includes the builds of Mac OS X Lion and iOS 5. And so with that, the time for GCC is coming to an end. Starting with Xcode 4.2, we're not going to be including a version of GCC anymore. It's going to be entirely replaced with LLVM, and our compiler transition is now complete.

When you switch compilers to LLVM, you actually get the choice of two compilers. The recommended choice is of course LLVM3. It's our fastest and most standards-compliant compiler. But for compatibility reasons, we are still including a version of LLVM GCC, which shares the front end, so the parser of the compiler, with the older GCC, and so it's fully source compatible, even if it doesn't implement the latest language features anymore.

So we're obviously putting a lot of energy behind LLVM. And we've taken it from a research project to a mature compiler product in just a few years. It has become the basis of many fantastic features in our tools. And now we're going to use it for our next big thing. So many of you have told us that at the top of your wish list of things we could do for you is bring a garbage collection to the iOS. And that's exactly what we are not going to do.

So instead, we're going to do something much better. It's going to take a few moments to explain. Let me start by comparing the advantages and disadvantages of garbage collection to manual memory management with retained release calls. So garbage collection makes it more straightforward and easy to write your code. And it also tends to reside in more stable applications, simply because you don't have to deal with a whole category of pointer problems anymore, like over-releasing objects, which can lead to crashes.

But unfortunately, garbage collection has an optimal impact on performance. Garbage can build up in your applications and increase the high watermark of your memory usage. And the collector tends to kick in at undeterministic times, which can lead to very high CPU usage and stutters in the user experience. And that's why garbage collection has not been acceptable to us on our mobile platforms.

In comparison, manual memory management with retainer release is harder to learn, and quite frankly, it's a bit of a pain in the ass. But it produces better and more predictable performance. And that's why we have chosen it as the basis for our memory management strategy. Because out there in the real world, high performance and stutter-free user experiences are what matters to our users.

But wouldn't it be nice if you could somehow get the best of both worlds and come up with a single strategy that combines all the advantages of these two approaches? And that's exactly what we are going to do. With LVM3, we are going to introduce automatic reference counting, or in short form, ARC. To tell you more about it, I'm going to hand over to Chris Lattner.

Thank you, Andreas. So Arc is based on a really simple idea. Let's take all the advantages of retain and release programming without those little disadvantages, like having to actually call retain and release. So to do this, we're taking memory management and pulling it into Objective-C, the language. Well, what does that mean? Well, that means primarily that retain and release are just going away. You don't have to worry about this anymore.

Now, This means that the compiler is in charge of the tedious and error-prone work of manually managing your memory, so you don't have to do that anymore. The compiler is really good at tedious things, right? But how does the compiler know where your retains and releases need to go? As Craig helpfully pointed out earlier on, for about two years now, we have been developing this tool called the Xcode Static Analyzer.

The analyzer is a fantastic tool that uses deep compiler analysis to walk through paths in your program and try to find bugs. It finds all kinds of bugs. It finds all kinds of crashers. You can dereference bad pointers. One of the most common kinds of problems that the static analyzer finds is memory management bugs.

So with Arc, we're taking one gigantic leap beyond the static analyzer, building this technology directly into the compiler, and having the compiler automatically synthesize, retain, and release for you. It's that simple. So let's talk about how the analyzer looks at your example. So here we have some code, has no retain or release in it, right? Well, it starts by saying, okay, I see you're allocating a string, and a string alloc returns ownership of an object.

Well, then you pass it to init. And it just returns the object. You pass it down as log. And this log doesn't really do anything to it. But wait, you just return from your function, and you haven't deallocated that object, right? There's nothing that points to it. There's an object that's been lost. And the analyzer says, hey, whoa, you've got a bug.

Why don't you go fix this? Well, now with Arc, you just don't have to do that anymore. So what does it mean to build memory management into the language? Well, retain, release, and auto-release, those are going away. Don't worry about those, right? I hope you're not too sad. I mean, maybe you're attached to them. I can't really help you out with that. I mean, you can choose not to use Arc if you want to, but you really should just use it.

But what does that mean for a good friend NS Auto-Release Pool? Well, I'm happy to say with Arc, the number of times you have to use explicit auto-release pools has been greatly reduced. Okay. Arc generally doesn't require you to deal with this unless you're dealing with some frameworks that are generating lots of auto-release garbage. In the case that you do want to use one, we're pulling it directly into the language with a direct syntax for defining a block statement for an auto-release pool.

This is much easier, more natural, and a lot faster than NSObd release pool was. Now, if you've gotten past the trouble of actually calling retain and release, there is still one more problem which you may have run into, and that's retain cycles. So let's talk about those next. And to explain what a retain cycle is, let's just look at one really quickly. So here we have three objects. We have an application object, we have a window object, we have a view object, and they're all connected together with retain properties.

So our app points to our window, our window points to our view, and oops, our view is connected back to our window. Maybe we added an outlet to our nib and just connected it up and didn't think about this. Well, what's the problem? Well, each of these objects has a retain count, right? So that window has two pointers pointing to it, and its retain count's two.

Now, when I close the window for my application, the app drops its reference to that window, and its retain count drops to one. Now, you'd expect that all those objects would go away, right? Well, unfortunately, there's still a retain count on both of them, so neither of them get deallocated, so we have a memory leak.

Well, this is a pretty bad bug. You know, you're leaking memory. Oh, well, is it really that bad, though? I mean, you're leaking two objects. Is it that big of a deal? The big problem with retain cycles is not these two objects you just leaked, but, you know, these two objects may point to megabytes of other objects.

It may point to your document, and who knows what that points to, right? And all of those objects are transitively leaked. Retain cycles can be one of the nastiest causes and problems with memory leaks that you can have, right? Well, I'm pleased to say that, in addition to introducing Arc, we're tackling this problem head-on with the introduction of zeroing weak references. And let me tell you about that.

Zeroing weak references, you can think of kind of like a non-retained IVAR. So they're very similar to a non-retained IVAR, but a heck of a lot safer. And let me show you why. So just like a non-retained IVAR, you can see that the weak pointer that I've replaced the back edge of my graph with is not increasing the retain count in my window. And so when I close my window, its retain count drops to zero.

Wait a second. Automatically, transparently, and completely safely, that weak reference just dropped to nil. I didn't have to do anything with my code, it just dropped to nil, making it impossible for me to dereference a dangling pointer. This takes the second major cause of crashes from your applications and defines it away.

Now, of course, that window has a retain count of zero, so it gets deallocated. Your view gets deallocated. Your document and everything else that's reachable from those things is now gone, right? And so we've solved our problem. So we think that between Arc and zeroing weak references, we've taken some of the most common classes of leaks and crashes from your application and have completely defined them away. We think this is a fantastic result. Now, we're so excited about this, we've actually converted all the new project templates in Xcode 4.2 to default to Arc. That means that if you create a new app, you've already got Arc. You don't have anything to do.

But wait, how many of you already have apps? Maybe one or two of you, right? Well, so what do you do? Well, I'm pleased to say you just start over again and write a whole new app. You can use the fancy new Xcode Arc Migration Tool, which is built right into Xcode 4.2.

The Xcode Arc Migration Tool works automatically to move your application to Arc through three steps. The first step is to scan your issues. Now, it's an automatic tool, but it's not complete magic, and so it can handle almost everything, but there are some tricky cases it can't handle.

If there's a tricky case it can't handle, it tells you about it and asks you to help it out. Assuming that's not a problem, then, it goes through and actually rewrites all your code. So all those retains and releases, a whole bunch of other cruft in your code that Arc doesn't need anymore, gone.

Third step is it gives you a diff. It says, hey, here's what I've done. This is really great. And when you hit Accept, you now have a new shiny Arc app of your own. So instead of talking about this and waving a slide, how about we actually see it in action? So here we have the code for the Touch Fighter application, which is an iPhone app.

Matthew has been working on this for some time, and he's done a great job. He finally got his textures figured out. But he's not really up with the times, and so he built this as a manually referenced kind of app. Let's see if we can help him out. To do this, we go to the Edit menu, go to Refactor, and just down to Convert to Objective-C Arc. Now this is going to scan through my code, and it looks like it found a problem that it can't automatically handle. Let's see what it's talking about here.

If we jump here, we can say, oh, look, I have an NS Auto Release Pool going on. And it looks like this code is doing something pretty crazy here. It looks like somebody's been really clever and optimized this. So every fourth time through the loop, it actually drains the pool and then reallocates a new one. Okay. So the migrator can't handle anything that's this complicated, so we have to help it out.

Well, I'm just going to take the body of the loop, this is the actual meet, and cut it out. And this I'm just going to delete, because whoever did that was being probably a little bit more clever than they need to be. And use our new add auto release pool statement, right? I can put the body of the loop right back in, and now I don't need this outer pool either.

Okay, with that, I've fixed the problem. Let's try running the Migrator again and see what happens. And this time it finishes up its incremental scan and says, hey, well, everything looks good. I'd like to move you now. So we're going to hit Next. It's going to go through our entire application and convert away.

And here comes our diff. Now, the first thing, which is pretty obvious, is that you can see that the migrators touch just about every file in our application. Well, this isn't because a migrator wants to touch all your code. This is because memory management logic gets scattered throughout your application.

This is just the way it is. This is why memory management in a manual way can be so tricky, because everything has to be spread across your app, and it all has to be perfect. So if we look at some of the changes the migrators made, we'll start with explosions.

Those are the most important part of any game. You can see what you'd expect. You'd see a lot of releases that just disappear. You look at this cube map, for example, and again, there's a whole bunch of routines that are just gone. Well, here you see a very common pattern.

So let's say you've written a dialog that just does a release. Well, with Arc, the runtime and compiler just do this for you, so you don't have to think about it. You don't have to worry about it. And so here, Arc's just deleting the entire dialog method, because it's not needed. Right? As I said before, the Migrator is actually pretty smart. So here's a case where I was using NSAutoReleasePool in main. Maybe you have a main that does one as well. And it just automatically, transparently migrated to an atAutoReleasePool, because it's well-structured.

Now, the Migrator has a whole bunch of tricks, and I'm not going to go through them all. One last one I want to show you is that the Migrator even knows how to change assigned properties and delegates and things like that to weak pointers for you. This means that the Migrator just makes your application safer and less crashy just by going through it, as well as defining away a lot of other problems.

So this all looks good to me. I'm just going to accept the changes. And let's see what happens when I try to run this app. So we're building it. Up comes the simulator. Go into single player here. And I'm not going to try to defend the world, but you can see that here we're running Touch Fighter with no retains and releases whatsoever. It's that simple.

Now I want to show you another application I've been working with and kind of playing with and converting in my spare time. This is an application called Dashcode. Dashcode is a slightly larger application. It's actually our premier developer tool for building web applications. So I've converted dash code in my spare time to Arc, and I've been fiddling around with the template chooser, and I think I might have introduced a problem. So let's see what happens when I profile it and run it under leaks.

Xcode is a big app, it has a little over 150,000 lines of code. So this is a real world app. Here comes Instruments in leaks mode. Here comes my template chooser I've been playing with. And even just sitting here, I can see, wait a second, Instruments is already telling me that I'm leaking memory.

This little red box is saying, hey, there's something wrong. And so I can look through this, and it looks like I have a problem. I am leaking NSCF strings, I'm leaking mutable dictionaries, I'm leaking some malloc memory, I'm leaking URLs. Clearly, I'm not very good at this whole thing, right? I mean, what's going on here? Well, one of the great new features of instruments in Xcode 4.2 is actually can search for retained cycles in the heap and display them to you graphically just by going to the cycles view.

So if I go here... I instantly see the problem, right? Clearly, I have several retain cycles in my application, and I can see graphically what's going on. I have a template library, points to mutable dictionary, points to template. That all makes sense. But the template is retaining the template library. That doesn't make sense.

So Instruments is super powerful, and it can just display this and find this for me. It's fantastic. So now that I know what the problem here is, okay, my template should not be owning my template library, what do I do? Well, I have to go back and find this in my code and do something about it. One of the other great features is because the compiler and Instruments are working together, is I can now just double-click right on this edge. It takes me right to the IVAR in question.

Now, I could change this to an unretained IVAR. I can make it a signed property, all that kind of stuff. But that's not really the right way to go. The correct, safe, nice way to go is to just make this into a weak IVAR. It's that simple. Now let's run this again under Instruments and see what happens. So here we go. And suddenly here comes Xcode with my template browser. And already we can see that there's no more leak. So all of those objects, which was a substantial leak, has been dramatically fixed just by switching to a weak IVAR. So that's Instruments.

So we're really excited about Arc. We're really excited about zeroing weak references. But you may be wondering, well, what's the cost? What does it mean if I switch my application to use this? So let's talk about performance. Now, in addition to implementing Arc and zeroing weak references, we've actually put a lot of effort into tuning up the Objective-C runtime itself. So what does that mean? For example, the retain and release implementation on NSObject now takes as few as 40% of the CPU cycles as it did before. This is a major speed-up.

Also, before I converted this NSA release pool, this hand-tuned case to at-order release pool, is that going to cost me performance, right? I mean, clearly somebody thought that it was important, so they put a lot of effort into doing this, or maybe they're a little bit more clever than they really deserve to be.

But in either case, the new at-order release pool syntax is much faster than NSA release pool. It takes about 20% of the time, 20% of the CPU cycles, because it's not actually allocating an object, right? And it's just implemented in a much more optimal way. It's really great.

Third thing I want to talk about is that the compiler and runtime were co-designed for Arc. They're working really well and really tightly together, which enables a number of really amazing optimizations in the LLVM compiler. So one of these optimizations is to take a really common pattern, auto-release getters. The standard Cocoa practice is to return an object auto-released. But that means that it lives a long time, and that means that it may not get deallocated for longer than you want, maybe at the top of your event loop.

Well, with Arc now, we're doing two things. The first is that the runtime and the compiler know when you're returning back to Arc. Second is, in that case, the runtime actually avoids putting that object in an auto-release pool at all. This is a huge performance win. So the cost of doing these auto-release getters when the optimization kicks in is now 5% in CPU cycles than it used to be. This is a major win.

The second big win of this, of course, is not a CPU performance optimization. It's the huge memory optimization, because now these things aren't going into an auto-release pool, and so that means they get deallocated as soon as the last pointer of them goes away. And that's really the huge advantage of Arc versus a garbage collector, is that your objects go away right away when they're dead. and So this is pretty great. We're really excited about this. Where do you think that you can use Arc? Well, I'm pleased to say that Arc is available on both of the premier platforms we announced earlier today, iOS 5 and Mac OS Online.

and going a little bit farther, Arc is so great that the first application is already in the store. Maybe you've seen it. This is the WWDC attendee app. Now, switching to Arc actually saved this app a substantial amount of memory. It also shrunk the code by about 5%, which is a huge maintenance win and has many other benefits as well. But you may be wondering, how many of you all are running this on iOS 5 or Lion? I don't know. Well, that's-- you're not, and that's because Arc also works all the way back to iOS 4 and Snowletter.

So we're obviously really excited about Arc. We think that this is a great answer to many of the problems you've had with your applications' memory use and memory management. And so we can't wait to see what you do within your own applications. Back to you, Andreas. Thank you, Chris.

So many of you have told us that memory management is one of the biggest hurdles for quickly developing apps on our platforms. And with Arc, we think we have the right answer for you. It gives us the right stutter-free performance. It makes your applications more robust. And it makes your code easier to write. So we think Arc is going to be a big deal, and we think you're going to be very happy with it.

So for the last hour, we've shown you a preview of several features that are coming your way in the tools. And today, we're going to make them available to you as several developer previews. If you want to get your applications ready for Mac OS X Lion, go and download the Xcode 4.1 developer preview from the WWDC attendee website. It contains everything you need for Lion to get your applications ready for the Mac App Store.

If you want to get your applications ready for iOS 5 later this year, go and download the Xcode 4.2 developer preview today, which is available as a preview running both on Snow Leopard and on Lion. So with that, we come to an end of the session. Hope you enjoyed it, and have a wonderful conference.