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 […] By Tony Dahbura.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
How To Enable ARC in a Cocos2D 2.X Project
25 mins
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 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 raywenderlich.com 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!
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:
./install-templates.sh -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.
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:
-fno-objc-arc
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;
@end
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.