DRAFT
##Outline
- Introduction, First Application
- Objective-C Refresher: Console App
- Foundation Classes, XCode and Interface Builder
- Memory Management
- Using Views
- Controllers
- Accelerometer
- Table Views and Controllers
- MVC Application
- Navigation
- Animation
###Exercises
- Hello World
- Basic gui app
- Larger, multi-week, "twitter-like"
- Final Project
##Technical Pre-Requisites
- Required: Mac OS X Leopard (version 10.5) or above
- Be register as Apple Developer
- iPhone Developer Program membership ($99 a year). If you want to do on-device testing, that is on a iPhone or iPad connected to your computer, you need to join, or else you're limited to the iPhone Simulator in xCode. or can investigate if available if you are part of an educational institution.
- Xcode for your MacOS Version, e.g. Snow Leopard + .iOS SDK is distributed as part of XCode and you can start building apps for iPhone/iPad and test them in the Simulator. The SDK is an object-orinted library which is a framework for creating the apps.
- Optional but Recommended: iPhone, iPad or iPod Touch
Note: Be aware each major iOS release, especially 4.x and 5.x aren't supported on some of the older devices.
"On device development" vs. using the iPhone Simulator. Simulator runs on the mac and shows you what the app will look like device, or can run on iPhone/pad connected to your Mac. Phase I = on mac, rapid iteration, Phase II- final, also can test w/ accelerometer*
##Pre-Requisite Knowledge
- Some experience with an object-oriented programming language,
- Some experience and comfort level using an integrated development environment (IDE),
- Experienced and familiarity learning, or refreshing yourself on programming concepts, such as design patterns, and programming paradigms.
##Key Points on Programming
- Cocoa Touch ('CT') is the API for building apps on iPHone, iPAD and Ipod touch rfrom Apple. It's written mainly in Objective-C
- CT follows a MVC (Model View Controller Software Architecture)
- CT is the highest level (vs. lowest of) of technologies on these devices; provides highest level of abstraction, and most developer productivity for creating end-user applications.
- CT has a lot of OO design patterns available in the framework
- CT: enables animation, multitasking, and gesture recognition
##Key iPhone Concepts
- Apps are made up of multiple objects, such as buttons, labels, etc. This are called view
- A window is the main application object, which is like a canvas that contains all app objects.
##Xcode in General
Package with all the tools for developing for Macs, and iOS. Ones to know about:
- Development Environment, keywords, source code completion, debug.
- Compiler for converting your source into executable on your target device
- iOS Simulator
- Performance tools
##Creating Projects in Xcode:
-
Project represents all the code and resources needed for your app.
-
Code: the device instructions, in Objective-c
-
Resources: images, icons, etc.
-
Console: ????
-
Two types of files created in Xcode: .xib, and .plist
-
.xib is the the user interface for your app, represented in XML. (.nib file is the compiled version of your app.)
-
.plist are key value pairs used to configure your app.
-
Create an application by creating all the different view programmatically, or
-
You can use XCode Interface Builder, which is a drag-and-drop visual interface for adding user interface to your application and associated them to actions. It has many pre-built application elements (tables, sliders, etc.)
##Interface Builder
- Interface Builder = Gui-based development, and object editor.
- Library: prebuilt objects you can reuse and customize (for view and controller)
- Window: visual representation of your current app
- Inspector: Properties of any element selected in Window, including window itself. Properties are clustered into sets.
##Creating a First App
MainWindow.xib = primary focus of our work...In Interface Builder, it is opens as The Doc Window.
By default, all apps will have this in their MainWindow.xib:
- File's Owner: event queue for the application are handled here
- First Responder: has to do with Cocoa Event-Handling model and which object responds first to a user-driven event. (Don't have to get into detail about it now....)
- QuizAppDelegate: controller for the overall application.
- Window object
NOTE: Earlier versions of IB had Actions in the inspector. They appear under the object in the Library in Xcode 4.3.
##Object Basics
Action: Behavior/Method Outlets: State, Instance variables
##Model-View-Controller
This is a design pattern used frequently in object-oriented programming and you'll see it in iPhone development:
- View objects are visible to the user, such as buttons, text, and menus.
- Model objects contain data, which can be from a file, a database, or other source. Typically model objects have no access to instance variables in view objects, but controller objects can access data from a model. Similarly, view objects have no direct access to instance variables/objects in model objects.
- Controllers provide a link between the user interface and the system. They can arrange for the right views to be displayed, and they can typically access data from both model objects and instance variables in application views.
###Topics
- Design patterns
- View controllers
- Displaying Data
- Dealing with Local and Remote data
- Text input
- Multithreading
- Address Book and other system integration
##iOS high Level
- A lot of functionality derived Mac OS X, then adapted for functionality on a mobile device.
- Pieces in common: os/unix, core app services, media, then big diff is Cocoa Touch
- CoreOS: Kernel, security, BSD, Sockets (rare to use)
- Core servies: address book, networking, file acces, Sqlite, collections
- Media: Audio, video, OpenAL
- Cocoa Touch: Multi-touch event, alerts, web vivew, view hierarchy, image picker, controllers, web views
##Object Review
- Object = thing = behavior + state (numbers, string, booleans, pointer to other object/helper)
- Outlets: Connect controllers to views. They are pointers that reference.....
- Action: Method
- Connections Inspector: see object in view available to be connected, make the connection
###Building Code Files:
- Quick way in IB is to do File > Write Class File and associate with existing app.
- This generates two files for class: header and method file (.h and .m) .m is where you add your code.... -.h files are header files which contain actual method declarations and instance variables for the methods. -.m files contains code for the methods (actual implementation, operations that occur when method executes.)
Note: Word of explaination about "NS" thats the prefix for all many objects in Objective-C
###Making Connections:
- After you create view objects, controllers, and controller actions/methods, you create connections so that the UI objects can trigger actions in the controller, and likewise a controller can possibly update the state of the UI. -You drag from the object with the pointer (e.g. Controller objects) and to the object that you want that pointer to point at (primarily Views).
###Setting Targets and Actions
- When a UI object is used need know what method/action to trigger, and it needs to know who (or which object/Controller) will be sent a message. The former is the action, the latter, the target.
- In Interface Builder you Control-drag the view object to the controller and under the controller, the appropriate action.
##Event-driven Programming in iOS
This basically means the flow of the program is driven by events, such as user actions, messages from other programs, or other application process.
Here's the basic process that occurs over and over in an iOS app:
- Application waits for an event to occur
- When the user touches the screen, this event is sent to the view that was touched
- The view sends a message to a controller to run a specific controller method.
- The controller method changes the state of view, which redraws itself and updates the screen.
This process is called an event loop.
##Application Properties
Every application you create will have a file called your_app_name.plist. This in the Resources folder of your application.
- Drag the icon from Finder to the Resources folder in Xcode.
###Useful Resources:
- Apple Developer iOS Human Interface Guidelines: http://developer.apple.com/library/ios/#DOCUMENTATION/UserExperience/Conceptual/MobileHIG/UIElementGuidelines/UIElementGuidelines.html
- Xcode Help: especially Reference Library Resources
- Objective-C: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Introduction/introObjectiveC.html http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/OOP_ObjC/Introduction/Introduction.html
##Refresher on Object-Oriented Programming
-
Class: is like standardized blueprint or recipe for objects in an application. It defines how an object should behave and what kinds of data it contains. E.g. Cat should eat, meow, and have four sets of retractable claws.
-
Instance: an actual unique object that exists and is based on a class. E.g. Charlie is a cat (a calico specifically.)
-
Method: operations that an object can perform. e.g. Charlie can climb up a chair.
-
Instance Variable: information that belongs to a specific object; this information is unique to the object. e.g. Charlie has green eyes.
-
Encapsulation: Keep implementation private and separate from the interface. E.g. you can have a method that authenticates a user (checks username and password), other parts of the application know when to go to it (before a user can add a comment), but the other parts of the programming do not have to know how the authentication process actually happens.
-
Polymorphism: Different objects can have the same interface. Methods across objects have functions that are structured and operate in a common way.
-
Inheritance: One object inherits behavior, or data (characteristics) from a class. E.g. your pet cat can scratch and climb, as defined by all that inherit from the superclass Cat.
-
Introspection: You can ask a class or object what type of class it is.
-
Superclass: Defines behavior and data for a class. E.g. snakes have no legs and swallow their food whole.
-
Subclass: "inherit," or take on behavior and data from the superclass. The subclass cam also provide additional behavior/data. E.g. Vipers have all the behavior of snakes (legless, cannot chew) but also have hollow fangs to inject venom.
-
NSObject: The root of all other objects. This class defines the basic functionality that all other objects will have such as memory management, introspection.
##Review of Objective-C
- Objective-C = Language
- Cocoa = Library, framework for objects used in OSX and iOS
- In Objective-C, everything is an object, even a class.
- Objective-C, a superset of C
- Single inheritance
- Protocols define behavior that crosses classes. Can specify if behavior mandatory or optional for a class with protocols.
- Dynamic runtime: classes are objects are looked up at runtime and appropriate implementation of their methods used at this point (vs. at compile-time)
- Can use loose or strong typing: can specify type of object or not.
###New Types
- id: used for an anonymous object (which does not have the object type explicitly defined)
- Class
- Selectors: function calls you make to an object
###Classes and Objects
- Objects represent something in the real world in an application, e.g. your car
- Attributes: belong to an object, and help define it, such as make and model.
- Actions: what an object can do, such as starting and turning.
- Classes describe attributes and actions for an object object. Serves as a template for all objects that are cars. Can also see it as a factory that creates cars on request:
- Object: you can ask a Car class to make you a new car, and it will create a car object by creating a placeholder in memory for it.
- Instance: the new car object is called an instance of the Car class.
- Message: if you want an object to perform one of its actions, you send it a message.
- Variables: Store information about a class or object.
- Objects: state/Data is maintained using instance variables which belong to an object.
- Classes: class variables belong to the class itself
- Methods: can belong to class or object too
- Instance methods are performed by individual objects
- Class methods typically create new instances or maintain some property which applies to all the class
- Behavior is expressed by methods.
- Instance variables are available using getter and setter methods
###Dot Syntax
Objective-C 2.0 introduced dot syntax used to separate object and method being called from that object, including getter/setter methods (also known as attribute accessors)
This is similar to other languages, such as Java or Ruby, and is converted by the compiler into the appropriate method call and object:
int edition = book1.edition //sets value of edition to the edition from a book object.
[[book volume] setEdition:latestEdition] is equivalent to:
book.volume.edition = latestEdition //sets edition for a volume of a book to the value latest Edition
####Using Methods
To get an object to execute one of its methods you send that object a message. Messages have three parts:
- Receiver: points to object being asked to execute its method
- Selector: name of method to be executed
- Arguments: how a method should execute, parameters provided to method
e.g. [arrayInstance addObject:anotherObject];
Can be called for instances/objects or classes. Note the semicolin to end each statement and in the case of a class method, you have a '+' starting the call, and for objects a '-' starts the call.
The following are examples of messages, including the bracket syntax:
[person doThis] [person doThis:argument] [person doThis:argument1 andArg:argument2]
First part of the statement is the object or class, and the second part is the method from the object/class you want to execute. The third part of a message are arguments, also known as parameters, which the method can operate on. Note that arguments are each paired with an appropriate label.
Use a colin after the method name to pass a parameter. Multiple parameters are in the form of parameterName:value.
Using Objective-C terminology,
- Message expression: [receiver method:argument]
- Message: is the method:argument in previous statement
- Selector: identifies the method in previous statement, can view it as the 'address' where a method actually lives.
- Method: code selected by a message
####Creating Objects
- Statically typed objects (predefine what type of object it is when you create the object.) Assuming a Person class exists, the syntax is:
Person teacher; // precedes an object name when you create it
Statically typed objects will be checked at compile time.
- Dynamically-typed objects (a.k.a. loosely typed objects):
id anObject;
In this case you are responsible for eventually know what this object can do and calling it appropriately (e.g. methods exist for the object when you refer to them.) Here you create a 'generic' NSObject, the most basic level of object.
Destroying objects:
[thisObject release];
Setting object to nothing/zero:
thisObject = nil;
####Types
Declaring object types can be done two ways:
id anObject // a dynamically typed object.
int yourAge = 34; //statically typed variable Person *anObject // statically typed
For statically typed objects, the compiler will catch errors and warn you if you are using the wrong type of object/data for a function. For dynamically typed objects, if you refer to data or functions that do not exist for the object the application crashes or hangs.
####Null Object/Nil
Indicates an object has no value:
- Testing for Nil:
- if (person == nil) return;
- if (!person) return; -As assignments and arguments:
- person = nil;
- [button setTarget: nil]
- Can call method on nil object, and it will return nil: person = nil; [person stateName];
####Booleans
Values = YES or NO:
BOOL flag = NO;
####Class Introspection
- Find out from an object what type of class it is
- Test if object derived from a more general superclass: isKindOfClass // YES if an object of that class or subclass
- Test if object part of specific class, including subclasses: isMemberOfClass // YES if an object of that class
####Class and Subclasses
-
the '-' means you are calling a method for an object
-
the '+' means you are calling a method from the class
####Identity and Equality
-
Identity: object1 == object2 // YES if we are referring to the same object in memory
-
Equality: object1 isEqual: object2 // YES if attributes from two objects are equivalent
-
Interpolation: "%@" formats and objects into a string representation.
-
Description: (NSString *)description; // Provides description of object
###Foundation Classes
Part of Cocoa, a series of libraries written in Objective-C and used in OSX and iOS development.
- Value and collection classes
- User defaults
- Archiving
- Notifications
- Undo manager
- Task, timers, threads
- File system, pipes, I/O, bundles
Major classes include:
-
NSObject, the foundation of all other objects. This means at minimum all other classes on Objective-C will inherit some methods and attributes from this class.
-
NSString: @"this string" // @ symbol creates the NSString object
- %@; outputs the string content
- [Variety of string methods]
-
Collections
- Array: ordered collection -They contain pointer (locations) of objects -Can hold any type of Objective-C object -One array can contain different types of objects -But primitives, such as ints, or C structures cannot be held. -nil cannot be added, but you can add a NSNull object (which represents nil.)
- Dictionary: e.g. hash, key-value pairs
- Set: unordered collection
-
Enumeration
- for
- for (Object *obj in array) // similar to Ruby each
-
NSNumber: variety of math functions
Example of creating a class:
-
In Xcode select File | New File.
-
In the Mac OS X section, select Cocoa Class.
-
Select Objective-C class.
-
In the dropdown Subclass of, select NSObject.
-
Click Next.
Xcode create your Objective-C class as two files, a header file and an implementation file (suffixed with .h and .m respectively):
- The header declares the new class, its superclass, instance variables, and methods for the class.
- The .m file is where you provide code for implementing methods for the class.
###Using Mutable and Immutable Objects
Mutable objects, such as arrays can be changed or you can add to them. Immutable objects such as NSArray is immutable, meaning you cannot add or remove objects after the array is originally (it is a read-only array.)
Major classes that come in mutable and immutable forms are arrays, sets, dictionaries, strings, data.
###Arrays
Arrays are container that can contain a ordered list of objects. An array does not contain the objects themselves, rather references to each object are in the array. There are two types of arrays in Objective-C:
- NSArray: which is immutable, and cannot be changed
- NSMutableArray: you can use this if you want to add or remove objects
Arrays can contain any type of Objective-C object; but this means primitive data types (primitives), such as integers, cannot be contained. In these cases you need to create an object to represent the primitive and then add it to an array.
Note too that nil cannot be added to an array. To specify an empty array element, you would add the null object, NSNull:
[array addObject: [NSNull null]];
Array methods include:
-
Create: Typically it is easiest to create it, allocate memory for it, and initialize it at the same time.
NSMutableArray *items = [[NSMutableArray alloc] init]; //creates the array and initializes it
-
addObject: Adds an object to the end of the array.
[items addObject:@"this"];
-
objectAtIndex: Retrieves from the first array position.
NSString *object = [array objectAtIndex:0] //
-
count: Returns the number of items in an array as an integer
int num = [array count];
-
insertObject: Inserts object into an array at specific position, as long as the position is less than or equal to current number of items in the array.
int numObjects = [array count]; [array insertObject:object atIndex:numObjects];
####Using Faster Enumeration
Objective-C 2.0 including syntax changes to the language which includes something called fast enumeration. Typically you would use a counting mechanism to go through items in an array:
for (int i = 0, i< [items count]; i++) {
Possession *item = [items objectAtIndex:i];
NSLog(@"%@", item);
}
With fast enumeration you can express this in a concise manner (this is similar to ways of expressing it in other languages, such as Ruby):
for (Possession *items in items)
NSLog(@"%@", item);
This is also less error prone in that you are no longer likely to count to far and overpass the last item in an array.
###NSString
This class is used throughout CocoaTouch:
- @"string constant"
- NSString *aString = @"string"; // assigning strong to an NSString object
Outputting strings, uses %@ to extract the content from an string object:
NSString @aString = @"World"; NSString *log = [NSString stringWithFormat: @"Hello '%@'", aString];
Logs the content, Hello World
Concatenation uses stringByAppendingString method:
NSString *myString = @"Hello"; NSString *fullString;
fullString = [myString stringByAppendingString:@" world!"]; // assigns content "Hello World" to fullString object
####Enumeration
In many languages you need to do an iterator (i.e. for loop), Objective-C has a enumerator for arrays to make it simpler and readable (similar to do/each in Ruby):
The following are functional equivalents:
for (i=0, i < count; i++) { //do something }
for (Student *student in array) { //do something }
####Integers, Numbers, Floats
No mutable version.
####Subclassing in Objective-C
####Custom Classes
- Determine superclass (when in doubt, NSObject, the most generic)
- What properties
- What actions
####Methods, Selectors, Message
- Method is behavior that an object can do
- Selector, is the way to reference a method (in other languages, the method call and what it looks like, including parameters)
- Message, the actual execution of a selector on an object.
####Defining a Class
Classes have two parts, one is in the public header file (.h), and the actual implementation of method goes into the private .m file of a project.
@interface Possession : NSObject {
}
@end
Here we declare a class using the keywords @interface ClassName. The colin and name of the superclass follows. In Objective-C you can only inherit from one class.
@interface ClassName : SuperclassName
The curly bracket that follows a class declaration should contain any instance variables.
After the closing curly brace, any methods that this class implements should be declared. Any methods you declare here must have respective method implementations in the .m file for this class. If a method implementation is missing, you will get a compiler warning.
Finally the @end keyword completes the class declaration.
####Adding Variables
Variables are declared in the .h file of a class, and are placed right after the class declaration in curly braces:
@interface Possesion : NSObject {
NSString *possesionName;
NSString *serialNumber;
int valueInDollars;
NSDate *dateCreated;
}
Note that variables of type object have a * prefix and variables which are primitive data types do not.
####Accessors and Properties
After you have declared instance variables you need methods to get and set them. These methods are called accessors. In Objective-C 2.0 you use properties to access variables. The most basic way to declare a property is as follows:
@property int valueInDollars;
There are other elements you can add to a property declaration to make that variable read-only, and also to specify how that variable is handled in memory.
#####Declaring Properties
Property declaration are made in the header file after the curly brackets which end variable declarations:
@interface Possession : NSObjects { NSString *possesionName; NSString *serialNumber; int valueInDollars; NSDate *dateCreated; }
@property (nonatomic, copy) NSString *possessionName; @property (nonatomic, copy) NSString *serialNumber; @property (nonatomic) in valueInDollars; @property (nonatomic, readonly) NSDate *dateCreated;
@end
We make several settings for the properties:
- By default, properties are atomic, which means a lock must be used when getting or setting the variable. When we specify the property is nonatomic, we do not need a lock.
- Properties can be set to readonly; by default they can be read and overwritten.
- For setting a variable, there are different ways which impact memory allocation. The simplest is assignment, the other options are copy or retain.
#####Implementing Properties
After you declare properties in the header file, you still need to synthesize them, which provides the getters and setters for the properties. You do this in the .m implementation file for the class:
#import "Possesion.h"
@implementation Possesion
@synthesize possesionName, serialNumber, valueInDollars, dateCreated;
@end
You can also create a custom getter and setter which might perform other actions with a get or set method.
#####Overriding Methods
If your object inherits from a superclass and you want to customize a method for instances, you would override the method.
Basically you provide a different implementation for this method in your subclass in the .m file:
- (NSString *)description { NSString *descriptionString = [[NSString alloc] initWithFormat:@"%@ (%@): Worth $%d, Recording on %@", possessionName, serialNumber, valueInDollars, dateCreated]; return descriptionString; }
Note here we are not yet concerned about the memory management issue in the above code. We will address that later.
###Initializers
To create new object you first allocate memory for the object with alloc then initialize it with init. Since all objects inherit from NSObject, and init is the main initializer for NSObject, we refer to it as a designated initializer.
The designated initializer checks to see each instance variable has a value. If so, an new object is valid; that is, it will function predictably.
If we want to create objects based on given values, we update the header with a new initializer method:
@property (nonatomic, readonly) NSDate *dateCreated;
- (id)initWithPossessionName:(NSString *)name valueInDollars:(int)value serialNumber:(NSString *)sNumber; @end
This method takes three arguments and sets the variables for the new object as the three values. It returns id, which is a pointer to the new object.
#####Self
The keyword self is used so an object can send message to itself. It does not need to be declared, rather it is an implicit local variable that points to the object running the method.
When you return a pointer to the object running the method:
return self;
Sends a pointer to the object running the method. If, in the case the new object is not initialized, it will return nil.
#####Super
The keyword super is way to call a method implementation that belongs to the superclass for an object. Often you want to add custom implementation in a subclass and perform it on top of a superclass:
- (void)thisMethod { [super thisMethod]; [self doExtra]; }
#####Initializer Chain
What if you want to create an initializer but assume you might not have all values you want to create for an object. You can create another custom initializer, one that calls the designated initializer and provides it default values for the missing arguments.
- (id)initWithPossessionName: (NSString *) name
If you want to use subclass's designated initializer instead of the superclass's you need to specifically override that init in the subclass's implementation. Since the init method is already declared in the superclass we only need to update the .m file:
- (id)init
{
return [self initWithPossessionName:@"Possession"
valueInDollars:0
serialNumber:@""];
}
###Class Methods
There are times you might want to have methods at the class level. Class methods do not operate on an object nor do they have access to instance variables. To create a class method, declare it in the header file:
+ (id)randomPossession;
Notice that class method declarations start with '+' and instance methods start with a '-'.
###Exceptions and the Console
Typically the compiler catches errors in your code when you select Build and Run. For instance if you call a method that does not exist for an array, you get the error:
NSMutableArray may not respond to '-thisNewMethod'
Even if it catches an error and you try to run code in the Console, you will get output specific to the error. The key part to examine is the reason:
reason: '-[NSCFArray doSomethingWeird]: unrecognized selector sent to instance 0x10010c8b0'
In this example, the Console tells us we are using a selector (or method call) does not exist for an object. The '-' tells us that the error is for an object not a class, and the NSCFArray tells us it is for a Core Foundation array.
#####Header File
- Importing the library. We need to include the library that contains the class we are basing our class on. This loads the library and enable us to reference it. In this case NSObject is in the Foundation library:
#import <Foundation/Foundation.h>
- Declaring a class. In the code block, we start by naming it, and show it is based on NSObject.
@interface Person : NSObject { // some data NSString *name; int age; } // some methods - (NSString *)name; - (void)setName:(NSString *)value;
- (int)age;
- (void)setAge:(int)age;
- (Bool)canLegallyVote;
- (void)castBallot;
@end
-
Add instance variables (data that should belong to one of these objects):
NSString *name; int age;
-
Add methods, including methods that can get and set values:
-
(NSString *)name;
-
(void)setName:(NSString *)value;
-
(int)age;
-
(void)setAge:(int)age;
-
(Bool)canLegallyVote;
-
(void)castBallot;
-
Note the '-' at the start of methods. Recall that '-' means that it is a method of the object, not the class. '+' indicates a method is a class method and is performed by the class when called.
#####Creating .m Files
- Import the appropriate header file:
#import "Person.h"
@implementation
- (int)age { return age; } - (void)setAge:(int)value { age = value; }
// other methods
@end
- Add code for the different methods and their execution. Note in the example below, the 'self' keyword means perform the method age from this object.
- (BOOL)canLegallyVote { return ([self age] >= 18); }
- (void)castBallot { if ([self canLegallyVote]) { // do voting stuff } else { NSLog (@"I'm not allowed to vote!"); } }
####Superclass and Subclass
- super: keyword means you are calling the method from an object's superclass.
####Overriding a Method
There may be cases where you will want to take a superclasses' method, but customize it for the subclass. Examples:
- (id)init;
- (id)initWithName:(NSString *)name;
###Object Lifecycle
- Creating Objects
- Memory Management
- Destroying Objects
####Creating Objects
Two part process:
- alloc: Method allocate appropriate amount of memory to store object (like giving it a person an address for a home)
- init: Creates initial values and other setup for new object
Person *person = nil; // makes a generic person object
person = [[Person alloc] init]; // create space for new object, then initializes it
The equivalent, terser version on one line:
Person *person = [[Person alloc] init];
#Memory Management
One of the most important things that differentiates Objective-C from many other languages is memory management.
This is tricky for non-programmers and programmers alike, so the main point to understand is that handling memory is much more explicit in Objective-C. This means it is up to you, as the developer, to actively add things in your code to handle what is stored in the computer's random access memory (RAM) when your code runs.
In other languages, memory management is much more implicit. Memory management may be provided through garbage collection when your code runs. This means that the language and tools are designed so that you can create objects and data and it is automatically cleared out of memory to free up new space.
As easy as this sounds for the developer, the drawback is that most garbage collectors are far from perfect and efficient. Ultimately for languages like Objective with more explicit memory management, is it is one more one more thing for a developer to handle; the upside is that languages with more explicit forms of memory management tend to be efficient and fast.
##How Memory Works
iPhones, iPads and other mobile devices have less space for memory than other, physically larger devices such as laptops and workstations. So memory management is already more of an issue when you create an application. When your application starts an iPhone or iPad, it reserves a heap of memory from the RAM for the application. This heap is a pile of memory your application can use.
The two issues you face when managing memory are:
- Memory leaks: forgetting to free up memory when it is no longer needed.
- Premature deallocation: removing objects from memory when they are still needed by other objects.
##Memory Management Basics
After you are done using an object, it would just remain there in memory as an application runs. Over time, all the objects would collectively tie up too much memory, and that is why programs such as Objective-C have explicit ways to remove objects out of memory:
- Allocation: alloc
- Destruction: dealloc
The calls must be balanced, in other words for each allocation, you need to deallocate once, otherwise your application may leak or crash.
Example:
Person *person = nil; // create object
person = [[Person alloc] init]; // allocate memory and initialize object
[person doSomething];
[person release]; // this destroys
##Using Reference Counting
In Objective-C, objects are responsible for deallocating memory for themselves. But for the most part, you do not call -dealloc directly, you use reference counting which is built into all NSObjects.
Objects have a retain count, which serves as a score, which tells the object whether an object should remove itself from memory. Other objects can change an object's retain count, an thereby save the object for a longer time if it is still needed. This helps avoid premature deallocation and memory leaks.
In reference counting:
-
0 means an object is alive and valid; this is the default for objects
- +1 is added when objects are created as part of -copy and +alloc; need to specify when object will be removed
- retain: this adds 1 to a retain count
- release: this minuses 1 from retain count
- When retain count == 0 then object is automatically destroyed by dealloc
- Once destroyed, there is no retrieving an object
If you assign an object to another variable, it is not implicitly retained, so you still need to explicitly retain it. One thing to also do is after you release an object to set it to nil so you do not crash (no response will occur, but also no crash will either):
[person release];
person = nil;
[person doSomething]; // no response
Note: The only case where you would use dealloc is if you overwrite the dealloc method for your class, for instance to do some special closing tasks prior to destroying the object. In that case, you would have -[super dealloc] in your custom dealloc method.
##Managing Object Ownership
So what if you have an object that another one depends upon for a value or functionality? The issue here is how to handle an object that is used by another one and make sure that it is not destroyed while you are trying to accomplish something. There are two approaches:
- The method that uses the object should increase the retain count of the object. For instance in a setName method:
if (name != newName) { [name release]; name = [newName retain]; // increases retain count for name }
- The method that uses the object can make a copy it:
if (name != newName) { [name release]; name = [newName copy]; // copy returns a new object with retain count of 1 and we assign it to name }
##Releasing Instance Variables
As part of memory management, if you remove an object you will want to make sure that the instance variables associated with the object are also removed. Here is where you can explicitly override NSObject dealloc method with your own and release the variables:
@implementation Person
- (void)dealloc {
// cleanup
[name release]; // reduces retain count to 0
// call super to actually destroy whole object and variables
[super dealloc]
}
##Using Autorelease
In this case an object is released/removed, but not immediately. If the object is a return value for instance it would be retained for the method calling it and later released. This is especially useful for methods that return newly created objects.
-
(NSString *)fullName { NSString *result;
result = [[NSString alloc] initWithFormat:@"%@ %@", firstName, lastName]
[result autorelease];
return result; }
Typically methods that include an alloc, or copy, or new statement should then call autorelease. Most other methods automatically return autoreleased objects, so you do not have to call it explicitly:
NSMutableString *string = [NSMutableString string];
##Memory Management and Object Properties
These can be used to access object attributes you use properties. They include shortcuts for getter/setter methods, and you can use them to specify whether an attribute is read-only or if can also be overwritten. Finally you use properties to specify memory management rules:
- Updating the header with properties:
#import <Foundation/Foundation.h>
@interface Person { // instance variables NSString *name; int age; } // properties @property int age; @property (copy) NSString *name; @property (readonly) BOOL canLegallyVote;
- (void)castBallot; @end
- Updating the implementation:
@implementation Person
@synthesize age; // maps this value to attribute in header @synthesize name; // also maps value to attribute value - (BOOL)canLegallyVote { return (age > 17); }
@end
To distinguish read only properties from those that can be changed we use the keyword (readonly):
@property (readonly) BOOL canLegallyVote; @property int age; // by default read-write
To specify memory management for properties we use one of three keywords (assign, retain, or copy):
@property (assign) NSString *name; // assigns pointer @property (retain) NSString *name; // calls retain @property (copy) NSString *name; // calls copy
Even though an implemented property already has implicit getter/setter methods, you can still explicitly create a custom getter or setter:
@implementation Person
@synthesize age; @synthesize name;
- (void)setAge:(int)value { age = value; // do something else to age }
@end
Note that using dot syntax and properties will mean that any explicit getter or setter will be used. A regular assignment statement will simply update the attribute value using the default getter/setter and will perform no other operations as part of the get/set:
@implementation Person - (void)doSomething { name = @"Fred"; // changes ivar directly self.name = @"Fred"; // calls explicit setter method }
##Deploying an Application
This is where you need a iPhone Developer Program membership, if you do not already have one. It is in theory optional for learning development, since you can always do incremental development and testing in the simulator, but if you want to do testing on your device, you will need it. You also need it to provide the application in the iTunes store.
##Application Conventions
- For any iPhone application icon that displays in the device, the icon image must be a 57×57 pixel PNG file. You put them in the Resources folder of your project.
- For the iTunes store, icons need to be 512 x 521 pixels and can be JPEG or PNG. It needs to be in a Resources group called iTunesArtwork.