How To Enable ARC in a Cocos2D 2.X Project

This is a post by Tutorial Team Member Tony Dahbura, an independent iOS developer with FullMoon Manor LLC. You can also find him on Google+. Automatic Reference Counting (or ARC for short) makes memory management in your apps much easier. ARC’s major benefit is freeing you from worrying about whether you cleaned up that sprite […]


  • Other, Other, Other

This is a post by Tutorial Team Member Tony Dahbura, an independent iOS developer with FullMoon Manor LLC. You can also find him on .

Automatic Reference Counting (or ARC for short) makes memory management in your apps much easier.

ARC’s major benefit is freeing you from worrying about whether you cleaned up that sprite or image from your game. As you probably know, even a small memory leak can make your game behave unpredictably. And after all, nothing kills a great game experience like an application crash while in the heat of the action.

Another benefit of ARC is that since it takes care of memory management for you, it allows you to focus on game development. Every minute you have for development lets you get your app done faster! What’s not to like about that?

However, by default the Cocos2D templates do not have ARC enabled. So a common question is “how can I use ARC in a Cocos2D project?” This tutorial will show you how to do exactly that! :]

First you’ll build a simple ARC-enabled project from scratch. Then, it’s Return of the Ninjas Going Pew-Pew! You’ll take the classic game and learn how to update games made with Cocos2D 1.X to Cocos2D 2.X.

Ready to expand your ninja-skills? Keep reading to get started!

Getting Started

This tutorial is going to show you two ways to convert a project to use ARC. First, I’ll show you the manual way of doing things, for the learning experience. Then, I’ll show you a simpler way to save time.

In a rush? If you don’t have much time and just want to skip to the “easy way” of doing things, feel free to skip down to the “Xcode At Your Service” section!

Using ARC with Cocos2D v2.x is a half-and-half option – meaning that the Cocos2D core code will not be ARC-compliant, but the files for your own app will be. This way, you will get the benefit of using ARC, without the library creators having to go back and rewrite all those routines to be ARC-compliant.

First things first: if you don’t have Cocos2D v2.x installed, then you can download Cocos2D v2.x from the official website.

After you download and extract the code, install the Cocos2D project templates. Open a Terminal window to the directory where you extracted Cocos2D, and enter the following command:

./ -f -u

The above command will install the necessary Cocos2D templates so that they will be available via Xcode.

As with most example programming projects, you’re going to create a Hello World! project. But this time, in addition to using Cocos2D, the project will also be ARC-enabled!

Start up Xcode and create a new Cocos2D v2.x project by selecting the iOS\Cocos2D v2.x\Cocos2D iOS template. Make sure to select the Cocos2D v2.x template list if you also have the older Cocos2D 1.x libraries installed. Click Next.

Name the project HelloWorldCocos, set the Company Identifier (if necessary, or you can leave it as-is) and change the Device Family to iPhone. Click Next, select a location for your project on your hard disk, and click Create.

Now build and run the template to make sure everything is working correctly. You should see the following:

Note: If your app appears in portrait mode instead of landscape, simply go to the project settings by tapping on the project root in the Project Navigator, select the HelloWorldCocos target, and select the Summary tab. Then disable the portrait orientations from the list of supported interface orientations.

Your app currently runs using the new Cocos2D libraries and without ARC, meaning that the standard memory management retain/release model is in use.

Hello, World! With ARC

It’s time to make your app ARC-enabled!

In Xcode’s Project Navigator (left sidebar), select your project root, then select the HelloWorldCocos target in the middle panel (if it is not already selected), then Build Phases, and expand the Compile Sources section (tap the triangle next to the section name to expand it).

You are going to mark the core Cocos2D files as not ARC-compliant, and hence allow them to continue to use the retain/release model. This is a new feature in Xcode: the ability to select a block of files and apply an option to them.

Select the first file in the list, CCAction.m, by clicking once on it. Then scroll the list of files to the bottom, hold down the shift key, and click on vec4.c. You should see a blue block similar to the following:

Double-click in the blue area (or you can tap Return – sometimes that works better) and a dialog box will drop down. In this dialog box, type the following and press Return:


All the selected files will now have the -fno-objc-arc compiler flag to the right of them, similar to the following:

You’ve just told the compiler not to apply ARC to these files. Instead, the compiler would treat them as it did before ARC came along.

Let’s turn on ARC for the remaining files.

Select the Build Settings tab and make sure All and Combined are selected. Scroll the display until you see Apple LLVM compiler 4.1 – Language at the top of the window.

Approximately 18 lines from the top of the options is one called Objective-C Automatic Reference Counting. (You can also simply type in ARC in to the search field to find the ARC setting.) It contains a drop down with a value of Yes or No. Right now the value is No. Select the value and change it to Yes.

Build your application.

You will see a series of errors on several files, in this case main.m, AppDelegate.m, and HelloWorldLayer.m. These files were not marked with the -fno-objc-arc setting earlier, and the compiler is unhappy that they are not ARC-compliant.

Let’s fix that!

Select the Project Navigator (the folder icon underneath the Run button on the left sidebar) and expand the Supporting Files folder. Select the main.m file:

The use of NSAutoReleasePool is not valid under ARC. So replace the main method with the following:

int main(int argc, char *argv[]) {
    @autoreleasepool {
        int retVal = UIApplicationMain(argc, argv, nil, @"AppController");
        return retVal;

The ARC model uses the @autoreleasepool statement where you enclose the code that will use the pool within braces. This is much cleaner and easier to follow.

Build your project again.


Not a pretty picture. :]

Xcode indicates that there are still code issues in AppDelegate.m and HelloWorldLayer.m. The main problems are the use of release and calling [super dealloc], since ARC automatically handles making these calls.

You can tap on each line shown on the Issue Navigator (the view shown above) and Xcode will take you to the relevant line in the relevant file. In this way, you can move through all the issues quickly, removing the release and [super dealloc] calls. Do that now.

Build your project again, and if you removed all the offending instances of release and [super dealloc], your code should compile fine. If you see any remaining issues, go through them and fix as before.

Even though your code should now be compiling fine, there is one more file to fix, and that is AppDelegate.h. This file contains a property, and ARC needs to know how it should be handled.

The specific property is the director_ property, which Cocos2D has commented in the template as a weak reference. Modify your AppDelegate.h file so that it looks like the following, in order to let ARC know about the weak reference:

#import <UIKit/UIKit.h>
#import "cocos2d.h"

@interface AppController : NSObject <UIApplicationDelegate, CCDirectorDelegate>
	UIWindow *window_;
	UINavigationController *navController_;
	CCDirectorIOS	*__unsafe_unretained director_;	// weak ref

@property (nonatomic, strong) UIWindow *window;
@property (readonly) UINavigationController *navController;
@property (unsafe_unretained, readonly) CCDirectorIOS *director;


Notice the addition of the __unsafe_unretained to the variable declaration and the @property declaration, as well as the change to the window property, where now it’s declared as strong instead of retain. While strong and retain essentially mean the same thing (that the property will be retained), strong is the correct form to use with ARC.

Build and run again.

Woohoo! You are up and running with ARC now!

You have your project set to use ARC, and you are using the Cocos2D library. This project is ready for your gaming creativity to take flight. :]

Now that you understand how to start a new Cocos2D project and manually convert it to support ARC, let’s look at an alternative method of accomplishing this, with some assistance from Xcode.

Xcode At Your Service

Apple recognized that many developers would want to embrace ARC, and has provided tools to assist in the transition. Since you know the steps to do the work manually, and understand what is involved, let’s look at converting an older Cocos2D project from 1.0 to 2.x and enabling ARC support.

Note: You can use the same techniques shown in this section to take any of the older tutorials from this site written for Cocos2D 1.X, and update them to Cocos2D 2.X and ARC!

Also, you can use these techniques to convert a new project made with the Cocos2D template to enable ARC just as you did in the last section – but even easier! :]

And what better place to use your new skills than the project from the first ever Cocos2D tutorial on Ray’s website? That’s right, the Ninjas Going Pew-Pew!

Ninjas Going Pew-Pew!

Ninjas Going Pew-Pew!

You are not going to spend a lot of time going over the ins and outs of the game itself, as the original tutorial does this wonderfully. Instead, you are going to focus on the necessary steps to get it working with Cocos2D v2.x, and then enabling ARC.

To save time, download the source project from here.

Extract the ZIP file to a convenient location. You will selectively grab pieces from this project and add them to the new converted version of the game that you will create.

Start up Xcode and create a new project using the iOS\Cocos2D v2.x\Cocos2D iOS template, and click Next. Name the project PewPewNinjas, set the Device Family to iPhone, click Next, choose a folder to save your project in, and click Create.


First add the game resources, including the sound effects and graphics, from the old game.

Locate the folder where you extracted the original game and open the Resources folder. Select the background-music-aac.caf file by clicking on it. Then hold down the Command key and click on ItunesArtwork, logo6.png, pew-pew-lei.caf, Player.png, Projectile.png, and Target.png. Drag these files over to your Xcode window and place the cursor right over the folder named Resources, and let go.

When the dialog box appears, make sure the Copy items into destination group’s folder is checked, and that PewPewNinjas is checked under Add to targets.

Click the Finish button. You have just copied over the graphic and sound effects into your new Cocos2D v2.x project! The Resources folder of your project should now look like this:

Build and run your application.

The application will show the same old Hello World screen, since you have not modified the code yet. It’s time to fix that!

One advantage of selectively adding files is that you can take advantage of new capabilities in the template code. This is the case in this effort, since you should be using the new AppDelegate files rather than bringing the older Cocos2D 1.x files into the project.

Once again, go to your folder with the older game code and open the Classes folder. Select all the files from GameConfig.h to HelloWorldScene.m.

Drag these files into your new Xcode project’s PewPewNinjas folder. Make sure the Copy items into destination group’s folder is checked and that PewPewNinjas is checked for Add to targets on the dialog.

Click the Finish button. Your Xcode project file view should look something like this:

You might wonder why some class files weren’t copied over. They simply aren’t needed with the new model.

Now let’s see what it will take to get PewPewNinjas running under Cocos2D 2.x by building the project again.

Xcode will complain about multiple errors. These are due to changes to the Cocos2D API since 1.x. Let’s go through and fix those issues.

First, CCColorLayer does not exist in Cocos2D v2.x, so you need to adjust the files accordingly.

Select GameOverScene.h and change the @interface line to:

@interface GameOverLayer : CCLayer {

Then, select HelloWorldScene.h and change the @interface line to:

@interface HelloWorld : CCLayer

The older CCColorLayer also allowed setting the layer’s background color using initWithColor:. You need to fix this as well. Select GameOverScene.m and change the first line in GameOverLayer’s init from:

	if( (self=[super initWithColor:ccc4(255,255,255,255)] )) {


	if ((self=[super init])) {

Save your changes, then open HelloWorldScene.m. Locate the same line in HelloWorld’s init:

	if( (self=[super initWithColor:ccc4(255,255,255,255)] )) {

Change it to:

if ((self=[super init])) {

Build and run again.

Whoa, what happened? Where is your game?

The Cocos2D v2.x startup sequence begins with the AppDelegate. The AppDelegate loads the IntroLayer, which pauses for a second and then calls makeTransition, which then displays the HelloWorldLayer scene.

That is not your game code, but the standard HelloWorld scene from the template.

Select IntroLayer.m. You need to tell it about the new HelloWorldScene class and remove the import for the template’s HelloWorldLayer.h. The final #import section should look like:

// Import the interfaces
#import "IntroLayer.h"
#import "HelloWorldScene.h"

Scroll to the bottom. Replace makeTransition: with the following:

-(void)makeTransition:(ccTime)dt {
    [[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:1.0 scene:[HelloWorldScene node]]];

Then delete HelloWorldLayer.h and HelloWorldLayer.m from the project, since they are not needed anymore.

Build and run.


Your ninjas and aliens move in the dark. In may be in their nature to do such a thing, but you want to keep an eye on them! What happened?

Remember how you removed the initWithColor:ccc4(255,255,255,255) bit? That set the background color and alpha modes for the scenes. Since this call does not exist in Cocos2D v2.x, the scene must be set up to using the new API calls in Cocos2D 2.x to get the white background back.

In Cocos2D v2.x, this is done using a glClearColor(r,g,b,a) call directly to the openGL view.

Since the entire game uses a white background, what better place to set this than in the AppDelegate?

Open AppDelegate.m, locate application:didFinishLaunchingWithOptions:, scroll down to where the scene is added to the director, and enter:

glClearColor(255, 255, 255, 255);  //set your background to all white for all the scenes

Build and run.

Yippee! Your game is now running under Cocos2D v2.x, and it has the right background. Go grab a drink and take five. :] When you come back, you’ll begin the process of making the game ARC-compliant!

Here is the code for the PewPewNinjas app up to this point.

Enabling ARC For Your New Game Using Xcode

Are you back? OK, time to get to work again. :] In the last section, you took the old Cocos2D 1.x version of PewPewNinjas and converted it to run using Cocos2D 2.x. But the project is still old-skool: it isn’t ARC-compliant. Time to change that!

Open your project (if it isn’t already) and from the Xcode menu, select Edit\Refactor\Convert to Objective-C ARC.

Make sure the checkbox at the top is unchecked.

Select the drop-down arrow next to so that it expands to show all the source files in the project. Scroll to the bottom of the list of files and select main.m, AppDelegate.m, IntroLayer.m, GameOverScene.m, and HelloWorldScene.m.

This dialog asks for files that should be checked and corrected to be ARC-compatible. Since the Cocos2D core is not ARC-compliant, there should not be any files checked other than the five mentioned above. Click the Check button. You will be greeted by a dialog box asking you to confirm the changes.

Click Next.

After a brief period of analysis, you will see the five files you selected, plus some additional .h files that also need fixing. There’ll also be a split view where the left pane shows the needed changes, and the right pane shows the original source.

Click on AppDelegate.m and note the analyzer changes.

Look through each of the files so you can get a feel for the code changes made by Xcode.

Note that in AppDelegate.m, the analyzer completely removed the dealloc method. This is different from what you did earlier, where you removed the release calls but left the method intact. Of course, since there is no code in dealloc, it makes sense to remove the method completely.

This is a great time to learn about some of the differences between ARC and the traditional model of memory management. You will notice some of the following:

  • The retain keyword is replaced by strong.
  • All release and autorelease statements are removed.
  • [super dealloc] is removed.
  • The dealloc method is altogether removed where it isn’t needed/used.

Since you have no issues with the changes suggested by Xcode, click the Save button. You will be prompted as to whether Xcode should create a snapshot of your project before making all these changes. In this case, since it is a conversion from the base template, just select Disable.

You will now be returned to your project with the necessary changes in place for ARC. It’s as simple as that!

Summary of Changes Xcode Performed

Here’s a quick reference to what the wizard did for you:

In AppDelegate.h:

CCDirectorIOS	*__unsafe_unretained director_;
@property (nonatomic, strong) UIWindow *window;
@property (unsafe_unretained, readonly) CCDirectorIOS *director;

In AppDelegate.m:

  • Removed method – (void) dealloc

In GameOverScene.h:

@property (nonatomic, strong) CCLabelTTF *label;
@property (nonatomic, strong) GameOverLayer *layer;

In GameOverScene.m:

  • Removed two – (void) dealloc methods
[[CCDirector sharedDirector] replaceScene:[[HelloWorldScene alloc] init]];

In HelloWorldScene.h:

@property (nonatomic, strong) HelloWorld *layer;

In HelloWorldScene.m:

  • Removed method – (void) dealloc under HelloWorldScene implementation
  • Removed [targetsToDelete release];
  • Removed [projectilesToDelete release];
  • Modified method – (void) dealloc under HelloWorld implementation
- (void) dealloc
	// in case you have something to dealloc, do it in this method
	// in this particular example nothing needs to be released.
	// Cocos2D will automatically release all the children (Label)
	_targets = nil;
	_projectiles = nil;
	// don't forget to call "super dealloc"

In main.m:

  • Modified method int main
int main(int argc, char *argv[]) {
    @autoreleasepool {
      int retVal = UIApplicationMain(argc, argv, nil, @"AppController");
      return retVal;

Look around and check out the Build Settings for your project – you will see that the ARC flag has been set to YES.

Now build and run one final time. :]

Enjoy your new Cocos2D v2.x game utilizing ARC!

Where To Go From Here?

Here is the complete code for PewPewNinjas with the ARC conversions.

You covered several topics in this tutorial, including converting a Cocos2D game from 1.x to 2.x. The Cocos2D site has a migration guide that discusses code migration from 1.x to 2.x in detail.

To learn more about ARC and various issues you might run into converting projects, check out Chapters 2 and 3 in iOS 5 by Tutorials, Beginning and Intermediate ARC.

I hope you enjoyed this tutorial, and have fun converting your own Cocos2D projects to run under Cocos2d 2.x and ARC! I’d love to hear about your own conversion experiences in the forums.

This is a post by Tutorial Team Member Tony Dahbura, an independent iOS developer with FullMoon Manor LLC. You can also find him on .