by hankie on November 7th, 2008

Coming from environments that rely entirely on garbage collection, the reference counting scheme in Cocoa still bites me. As I’m trying to clean up after myself I sometimes release things I shouldn’t. My yesterday’s blunder was similar to this:

// add new person to the list
Person *person = [[Person alloc] init];
person.name = @"Joe";
[people addObject:person];
[person release]



I hear you: What was I thinking? I was thinking that the people collection (instance of NSMutableArray) will retain its elements as they are added, incrementing their reference count. This is, of course, not the case. Why would I expect such behavior?



Earlier I worked on a navigation app using table views. As the user taps on a row in a table view the app displays the detailed view of the selection:

PersonDetailController  *detailController = [[PersonDetailController alloc]
		initWithNibName:@"PersonDetailView"
		bundle:[NSBundle mainBundle]];
// omitted: assign selected person to detail controller
[self.navigationController pushViewController:detailController
		animated:YES];
[detailController release];



The navigation controller maintains a stack of view controllers, and because it retains the controllers pushed on the stack, we need to release the pointer.



It’s important to understand the behavior of components in Cocoa framework. Aaron Hillegass mentions two rules concerning release:

  • Objects created by alloc, new, copy, or mutableCopy have a retain count of 1 and are not in the autorelease pool.
  • If you get an object by any other method, assume that it as a retain count of 1 and is in the autorelease pool. If you do not wish it to be deallocated with the current autorelease pool, you must retain it.

by hankie on November 4th, 2008

I felt this gotcha coming. I got to the point when I needed to test and demo my first app on an actual device rather than in XCode simulator. I followed Apple’s directions (pdf) on how to run the app, but as soon as I hit “Build and Go” I somehow knew it wasn’t going to happen. Call it professional deformation… Anyway, to install and run your app on an iPhone, you need to do following:

  • Join the iPhone Developer Program Portal
  • Create certificate request
  • Obtain and install your iPhone Development Certificate
  • Create your App ID

  • Assign your testing devices
  • Create and download provisioning profiles

Now to the gotcha. After you’ve done the above, open your app’s info.plist file as a plain text file.
Change the string value under CFBundleIdentifier element to your AppID without the generated 10-digit prefix. For example, if the AppID associated with your provisioning profile is ABCDE12345.com.mycompany.myApp, the CFBundleIdentifier would be com.mycompany.myApp. Hit “Build and Go” and your app should install and run on the device. The post that saved a part of my night outlines alternative solutions, but I found this one the simple enough, and it does the job.