Wednesday, June 24, 2009

A way to display all possible typeahead values in XCode

As you enter code into the XCode IDE, the IDE will often attempt to complete the term for you by using a typeahead feature. To view all possible values that match the type-ahead, simply press the escape key when a partial term is displayed.




From Dave Mark's "Beginning iPhone Development: Exploring the iPhone SDK"

Monday, June 22, 2009

A shortcut to perform a keyword look-up within the XCode IDE

To look up a constant, variable, method or function in iPhone's documentation library diretly from within the XCode IDE, simply option+double-click on the term.

From Dave Mark's "Beginning iPhone Development: Exploring the iPhone SDK"

Sunday, June 21, 2009

Differences between Cocoa and Cocoa Touch

I learned...

According to Dave Mark in "Beginning iPhone Development: Exploring the iPhone SDK":

"If you are coming to iPhone with previous Cocoa experience, a few tools that you're probably accustomed to using aren't available on the iPhone. The iPhone SDK doesn't support Core Data or Cocoa Bindings. We mentioned earlier that Cocoa Touch uses Objective C 2.0, but one of the key new features of that language is not available on iPhone: Cocoa Touch does not support garbage collection."

Its a good thing I spent a lot of time reviewing memory management. It looks like those retain and release statements will come in handy. I'm also glad I stopped at Chapter 8 in "Cocoa(R) Programming for Mac(R) OS X (3rd Edition)" and picked up this new book. Core Data was only a few chapters away and I would have wasted lots of precious time learning something I wouldn't be able to use.

Currently reading "Beginning iPhone Development: Exploring the iPhone SDK" by Dave Mark & Jeff LaMarche



This Purchase: $26.39 | Running Total: $3008.11

The Benefit of Key-Value Coding

I am learning about Key-Value coding in Chapter 7 of "Cocoa(R) Programming for Mac(R) OS X (3rd Edition)".

I would say the most important lesson from this chapter is knowing what accessor methods are and when they get called. The author's tutorial in this chapter clearly demonstrates this behavior. In the tutorial, I implemented an AppController with two accessor methods "set" and "get".

The implementation of these methods were fundamentally simply.

"set" sets an instance variable in the AppController class to a specified value
"get" returns that value

The "set" accessor method got called when I used "setValue ... forKey".
e.g. [self setValue:[NSNumber numberWithInt:5] forKey:@"fido"];

The "get" accessor method got called when I used "valueForKey".
e.g. NSNumber *n = [self valueForKey:@"fido"];

The tutorial helped illustrate this by having me issue NSLog calls from within each accessor method. I was also taught how to bind key-value code to a graphical object, in this case a slider. When the slider moved, the NSLog calls showed the set and get methods being called in the GDB debug console window.

Thursday, June 18, 2009

How to create a new instance of an AppController in the NIB

Following the steps in Aaron Hillegass' SpeakLine tutorial in Chapter 5 of "Cocoa(R) Programming for Mac(R) OS X (3rd Edition)", I got lost on how to add the AppController to the nib. I found out this is what you need to do:

Assuming you've already added the "AppController.m" and "AppController.h" Objective C files to your project.

1. From Interface Builder, go to Tools > Library
2. Find NSObject under "Library - Cocoa - Objects & Controllers"
3. Drag that into the NIB window (i.e. - MainMenu.xib)
4. Rename the new NSObject to "AppController"
5. With the "AppController" object highlighted, go to Tools > Identity Inspector, drill down on the "Class" field and select "AppController"
6. Your AppController class is now added to the nib

Accessor Methods: "Retain, then Release" methodology

From "Cocoa(R) Programming for Mac(R) OS X (3rd Edition)" by Aaron Hillegass

If you have a nonpointer type, the accessor methods are quite simple. For example, if your class has an instance variable called foo of type int, you would create the following accessor methods:

- (int)foo
{
return foo;
}

-(void)setFoo:(int)x
{
foo = x;
}

MATTERS BECOME MORE COMPLICATED IF FOO IS A POINTER TO AN OBJECT. In the "setter" method, you need to make sure that the new value is retained and the old value released, as shown below:

-(void)setFoo:(NSCalendarDate *)x
{
[x retain];
[foo release];
foo = x;
}

Wednesday, June 17, 2009

I installed XCode but cannot find the executable. Where does it get installed?

Once you download and install XCode, the executable can be found here:

Macintosh HD > Developer > Applications > XCode

Debugging "objc[17695]: FREED(id): message release sent to freed object=0x1073d0"

Here's a good article on how to troubleshoot these kinds of errors:
http://www.cocoadev.com/index.pl?DebuggingAutorelease

Taken from the article:

One of the most opaque bugs I've had to deal with in Cocoa is leaving a released object in the autorelease pool, causing an EXC_BAD_ACCESS in NSPopAutoreleasePool?(). When this happens, it's pretty much impossible to tell what the doubly-released object was and where it was instantiated.

Fear no more! Using Cocoa's NSZombie? debugging class and the command-line malloc_history tool, we can nail this bug in a pinch.

Suppose you have the following (obviously incorrect) code:

  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSData* data = [NSData dataWithBytes:"asklaskdxjgr" length:12];

[data release];
[pool release];

The dataWithBytes: method sends an autorelease message to the created object, so we don't need to release it ourselves. When the autorelease pool is tossed the freed data object gets another release message, our app crashes, and we have no idea why.

The dataWithBytes: method sends an autorelease message to the created object, so we don't need to release it ourselves. When the autorelease pool is tossed the freed data object gets another release message, our app crashes, and we have no idea why.

Here's what we do:

Click on the "Targets" tab, open "Executables" and select the app (In XCode 2.0, double-click the executable in the file tree and select the arguments tab to enter environment variables). In the executable settings, add the following environment variables and set their values to "YES" (without the quotes):

  NSDebugEnabled
NSZombieEnabled
MallocStackLogging

You may also want the following environment variable set to YES:

  MallocStackLoggingNoCompact

With NSZombieEnabled, Cocoa sets an object's isa pointer to the NSZombie? class when its retain count drops to zero instead of deallocating it. Then when you send a message to an NSZombie? object (i.e., you're accessing freed data), it raises an exception and tells you where the object lives:

  2003-03-18 13:01:38.644 autoreleasebug[3939] *** *** Selector 'release'
sent to dealloced instance 0xa4e10 of class NSConcreteData.

Since you have MallocStackLogging turned on, you can now run "malloc_history

" to see the stack trace when the object was allocated:

  [dave@host193 Frameworks]$ malloc_history 3939 0xa4e10

Call [2] [arg=32]: thread_a0000dec |0x1000 | start | _start | main |
+[NSData dataWithBytes:length:] | NSAllocateObject | object_getIndexedIvars |
malloc_zone_calloc

if you run under gdb, you may enter:

 (gdb) shell malloc_history 3939 0xa4e10

And there it is: the double-released object was allocated with [NSData dataWithBytes:length:] in the function main()!

I love you, Cocoa!

Tuesday, June 16, 2009

Currently Reading "Cocoa(R) Programming for Mac(R) OS X (3rd Edition)" by Aaron Hillegass



This Purchase: $26.97 | Running Total: $2981.72

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

Friday, June 12, 2009

Lessons from the HelloWorld application

Creating the HelloWorld application opened my eyes to several things. Firstly, Objective-C and Cocoa are unlike any other programming language I've ever learned. The syntax is not very straight-forward. That means I'll probably have to spend a few weeks at the very least to learn the basics of Objective-C and Cocoa programming. Secondly, the concept of memory management for the iPhone is something that requires a lot of attention (i.e - is a bitch for the programmer).

"In general, however, you should try to avoid using autorelease wherever possible as it’s a more resource intensive operation than release."

Apple recommends that iPhone programmers follow these memory management guidelines:

To make sure it is clear when you own an object and when you do not, and what responsibilities you have as an owner, Cocoa sets the following policy:

  • You own any object you create.

    You “create” an object using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy).

  • If you own an object, you are responsible for relinquishing ownership when you have finished with it.

    You relinquish ownership of an object by sending it a release message or an autorelease message (autorelease is discussed in more detail in “Delayed Release”). In Cocoa terminology, relinquishing ownership of an object is typically referred to as “releasing” an object.

  • If you do not own an object, you must not release it.

This policy applies both to GUI-based Cocoa applications and to command-line Foundation tools.

The entire documentation can be found here:

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html#//apple_ref/doc/uid/10000011

HelloWorld! My first iPhone Application

Yesterday, I finally got Mac OSX 10.5 (Leopard) and the iPhone SDK installed on my new MacBook Air.

Since I've never built an iPhone application before, let alone used XCode or developed in Cocoa or Objective-C, I'm going to start by building the simplest app possible, the "Hello World" application.

http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhone101/Articles/01_Overview.html#//apple_ref/doc/uid/TP40007514-CH10-SW2

Sunday, June 7, 2009

4. Upgrading Mac OSX - iPhone SDK requires Mac OSX 10.5 (Leopard)



Apparently, Mac OSX 10.5 (Leopard) is required for the iPhone SDK, which means I'll need to reinstall my OS and spend a few extra bucks to get things going. Currently, I am on Mac OSX 10.4.11 (which isn't supported by the iPhone SDK)

My Purchase Summary:

Apple Mac OS X Version 10.5.6 Leopard [5-User Family Pack]: $126.99
Tax: N/A
Shipping: $4.39
Total: $131.38

This Purchase: $131.38 | Running Total: $2954.75

Saturday, June 6, 2009

3. Reviewing the iPhone Human Interface Guidelines

Since it is my goal to eventually get an application published on the Apple Store, I figured it'd be wise to read over what Apple expects from each app in terms of its design and user experience.

http://developer.apple.com/iphone/library/documentation/UserExperience/Conceptual/MobileHIG/index.html

Time spent: 5 hours

2. Installing the iPhone SDK

Apple will require you to join the iPhone Developer Program first.

It's free and easy. Do it!

http://developer.apple.com/iphone/index.action

1. Purchasing the goods... and getting some frequent flier miles in the process :)


Today I bought a MacBook Air and got an 8GB iPod Touch for free by taking advantage of Apple's "Back to School" special.

* Buy a qualifying Mac and iPod with your Apple education discount from May 27, 2009, through September 8, 2009, and receive an online rebate up to $229, except where otherwise required by state law. Terms and conditions apply. Visit www.apple.com/backtoschool for full details. Not all Apple products qualify for education pricing.

Details: http://store.apple.com/us/browse/campaigns/back_to_school?cid=WWW-NAUS-BTS20090507-00029

On top of that, I got 8000 United Frequent Flier miles. United is currently offering 3 miles for every 2 dollars spent if you access the Apple store through United's Mileage Plus storefront. If you spend $500 between April 10 2009 and June 21 2009, United will reward with with an addition 500 miles on top of that!

Here's a link to the United Mileage Plus storefront: http://links.mponlinemall.com/a/v.x?Token=pjbigcdjnlknmejeealefcebfdhplgeopjjcnpbnheocekhbkmfjblogedgpmgmjoomp


My Purchase Summary:
iPod touch 8GB: $299.00
iPod touch 8GB (mail-in rebate): -$299.00
MacBook Air, 13-inch, Aluminum (1.86 GHz/128GB Solid State Drive): $2,299.00
Apple Mighty Mouse: $49.00
Tax: $238.37
Shipping: Free
Total: $2,823.37

This Purchase: $2,823.37 | Running Total: $2,823.37