Tuesday, June 16, 2009

Before moving on. I think I really need to learn Objective C

So far, I've encountered enough code in Objective C in the Apple iPhone documentation to say that I'm lost Being new to the iPhone, with no prior experience in Cocoa nor Objective C, I found myself getting very little out of the articles I've read so far from Apple's dev center. I thought since I already knew how to program in Java, C, C++ and PHP that I would have enough of a programming background to learn Objective C as I go along but I was wrong. I found Objective C to be a language unlike any other I've ever seen before.

Today, I made the decision to spend some more time to focus on learning Objective C. Hopefully after a weeks time I'll have a stronger grasp of the language and then get back on track to create this iPhone application.

As a first step towards becoming more proficient in Objective C, I went to the bookstore today and picked up a book called "Cocoa Programming for Mac OS X". Chapter 3 is about Objective C and I found it to be a very well written and easy to digest introduction to the Objective C programming language. The introduction provided me with answers to a lot of the questions I had about the code snip-its in previous articles, such as why we use brackets so much [ ], why functions begin with -, why we don't explicitly declare private, protected and public classes and why Objective C makes such liberal use of the '@' character, to name a few.

Now, not only do I better understand what is going on, but I am beginning to see a benefit to doing things in Objective C. Check out Chatper 3 for yourself and you'll be surprised at how fast you will learn. The book is written by Aaron Hillegass and I highly recommend it:




I'll be spending the next week reading this book and I'll be going through this Objective C tutorial published by Apple.

Apple Objective-C Tutorial PDF

Monday, June 15, 2009

Memory Management: alloc vs. convenience constructor vs. accessor method. What is the difference and which is preferred?

The following simple examples illustrate the contrast between creating a new object using alloc, using a convenience constructor, and using an accessor method.

The first example creates a new string object using alloc: It must therefore be released.

- (void)printHello {
    NSString *string;
    string = [[NSString alloc] initWithString:@"Hello"];
    NSLog(string);
    [string release];
}

The second example creates a new string object using a convenience constructor: There is no additional work to do.

- (void)printHello {
    NSString *string;
    string = [NSString stringWithFormat:@"Hello"];
    NSLog(string);
}

The third example retrieves a string object using an accessor method: As with the convenience constructor, there is no additional work to do.

- (void)printWindowTitle {
    NSString *string;
    string = [myWindow title];
    NSLog(string);
}



According to Apple, using accessor methods is the preferred way to go. "Sometimes it might seem tedious or pedantic, but if you use accessor methods consistently the chances of having problems with memory
management decrease considerably. If you are using retain and release on instance variables throughout your code, you are almost certainly doing the wrong thing."

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html

Memory Management: rules to always keep in mind

  • Within a given block of code, the number of times you use copy, alloc and retain should equal the number of times you use release and autorelease.

  • You only own objects you created using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message.

  • Implement a dealloc method to release the instance variables you own.

  • You should never invoke dealloc directly (other than when you invoke super’s implementation in a custom dealloc method).


http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html

Memory Management: “reference counting” methods

You manipulate the retain count (take and relinquish ownership) using a variety of methods:
alloc

Allocates memory for an object, and returns it with retain count of 1.

You own objects you create using any method that starts with the word alloc or with the word new.

copy

Makes a copy of an object, and returns it with retain count of 1.

If you copy an object, you own the copy. This applies to any method that contains the word copy where “copy” refers to the object being returned.

retain

Increases the retain count of an object by 1.

Takes ownership of an object.

release

Decreases the retain count of an object by 1.

Relinquishes ownership of an object.

autorelease

Decreases the reference count of an object by 1 at some stage in the future.

Relinquishes ownership of an object at some stage in the future.

The rules for memory management are summarized as follows (see also “Memory Management Rules”):

  • Within a given block of code, the number of times you use copy, alloc and retain should equal the number of times you use release and autorelease.

  • You only own objects you created using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message.

  • Implement a dealloc method to release the instance variables you own.

  • You should never invoke dealloc directly (other than when you invoke super’s implementation in a custom dealloc method).


http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html

Memory Management: “reference counting” overview

Cocoa implements its ownership policy through a mechanism called “reference counting” or “retain counting.” When you create an object, it has a retain count of 1. When you send an object a retain message, its retain count is increased by 1. When you send an object a release message, its retain count is decreased by 1 (autorelease causes the retain count to be decremented in the future).

When its retain count drops to 0, an object’s memory is reclaimed—in Cocoa terminology it is “freed” or “deallocated.” When an object is deallocated, its dealloc method is invoked automatically. The role of the dealloc method is to free the object's own memory, and dispose of any resources it holds, including its object instance variables.

If your class has object instance variables, you must implement a dealloc method that releases them, and then invokes super's implementation. For example, if the Thingamajig class had name and sprockets instance variables, you would implement its dealloc method as follows:

- (void)dealloc
{
    [sprockets release];
    [name release];
    [super dealloc];
}

You should never invoke another object’s dealloc method directly.

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmObjectOwnership.html#//apple_ref/doc/uid/20000043-BEHDEDDB

Implementing Accessor Methods: @synthesize

In many cases you can (and should) avoid the need to implement your own accessor methods by using the Objective-C declared properties feature and asking the compiler to synthesize accessor methods for you:

@synthesize firstName;
@synthesize fullName;
@synthesize birthday;
@synthesize luckyNumber;

Even if you need to provide your own implementation, you should declare accessors using a declared property—you must ensure, of course, that your implementation meets the specification you give. (Note in particular that by default a declared property is atomic; if you don’t provide an atomic implementation, you should specify nonatomic in the declaration.)

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAccessorMethods.html#//apple_ref/doc/uid/TP40003539-SW1

Declaring Accessor Methods: @property

You should typically use the Objective-C declared properties feature to declare accessor methods (see Declared Properties in The Objective-C 2.0 Programming Language), for example:

@property (copy) NSString *firstName;
@property (readonly) NSString *fullName;
@property (retain) NSDate *birthday;
@property NSInteger luckyNumber;

The declaration makes explicit the memory management semantics for the property.

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAccessorMethods.html#//apple_ref/doc/uid/TP40003539-SW1