The lifespan of an object owned by NSMutableArray, or why Objective-C annoys me and Java makes me happy.

Hard to find memory bug on the iPhone.

I had to find it by (a) building the map file for the distribution of the iPhone product, and (b) walking for an hour around Santa Monica (pretty day, though a bit on the warm side) waiting for the map software component to crash.

I finally found it. It’s the sort of memory bug that Java programmers never have to concern themselves with.

So suppose you’re writing a queue, and you use an NSMutableArray. (In Java you’d use a LinkedList object, which would be faster, but I digress.) Removing the object from the NSMutableArray, I wrote:

MyObject *obj = [myMutableArray objectAtIndex:0];
[myMutableArray removeObjectAtIndex:0];
UseMyObject(obj);

And all is right in the world, correct?

Um, not quite.

See, there is thing thing called the autorelease pool. It’s quite clever: it holds a list of all the objects that, after this current event is finished being processed, the objects will be released and potentially deleted from the system. So when you get a return value back from some function, unless its a function which explicitly gives you ownership of the object, you can safely use that object until the end of the event processing loop, which certainly won’t happen until after your routine returns, right?

Um, not quite.

NSMutableArray notes in its documentation that on a call to the remove function removing that item from the array, release is called immediately on the object, which means my object obj above has been released. Now what makes this a hard to find bug is that while the object may have been deleted and its memory released, the object itself still lingers in memory unless you use a memory debugging library.

And unfortunately for me (1) the conditions causing this routine to be called is only triggered when walking around with our new software package, and (2) the various memory debugging libraries only work under the iPhone simulator.

The workaround?

MyObject *obj = [myMutableArray objectAtIndex:0];
[[obj retain] autorelease];  // before removeObjectAtIndex
[myMutableArray removeObjectAtIndex:0];
UseMyObject(obj);

Feh.

This is exactly the sort of stuff that garbage collection helps with, and is the primary reason why I like Java: no messing with object lifecycle management. Unfortunately garbage collected Objective C isn’t available on the iPhone, which means that so long as I’m trying to write Objective C code that runs on the iPhone and may also run on the Macintosh, I cannot use garbage collection in my Objective C development.

You know credit is tight when…

I got an offer from my bank to refinance my home mortgage. I’ve gotten these offers before, and the last time I did it I literally signed a single piece of paper–and the paperwork went through without any question.

This time I got an offer to refinance my mortgage to a fixed from the adjustable it used to be. Thinking it’d be the same process, I said sure.

Twenty three pages of supporting documentation later, and two documents missing (I need to call a couple of people to forward the documents) and I’m starting to feel like I’m receiving the financial equivalent of a proctological examination. Just as well: even though my current mortgage doesn’t adjust until 2011, I’d rather have the fixed mortgage–and I suspect my bank would like the updated financial information so they can repackage my mortgage as a high quality MBS rather than the junk that is floating around there, killing our banks.

iPhone SDK v2.1 gotcha.

The easiest way to load a NIB containing some element of your user interface on the iPhone is to call the UIKit addition to NSBundle loadNibNamed:owner:options:.

So throughout my code I have the following:

NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MyNIBFile" owner:self options:nil];
UIViewController *c = [nib objectAtIndex:1];

Um, there’s a problem here. On return the NSArray returned contains at index offset 0 a reference to the bundle; the first defined object is at 1 and so forth.

That is, on the iPhone 2.0 SDK.

Using the iPhone 2.1 SDK, the index starts at 0; a reference to the bundle is not returned. Thus, you need to change the statement above to:

UIViewController *c = [nib objectAtIndex:0];

Meh.

Naturally, of course, if I had used the iPhone SDK like the MacOS SDK, I would have set the file owner in the NIB to an object which contains IBOutlets for the items in the NIB being loaded. And had I done this, I wouldn’t have had a problem at all.

Four ways of using a mobile phone.

I’m starting to conclude there are four ways a user will interact with a phone. These four modes or four methods are:

(1) Checking incoming messages or current device status. This should be very quick and unobtrusive: you should be able to just press a button or two and get the status you want.

(2) Sending a message. This should also be relatively quick, though often people are willing to spend time composing messages, such as SMS messages or quick e-mail messages. And in this category I’d put chatting away on the phone: you’re involved with the device communicating to someone else.

(3) Searching for something. This may wind up being involved, but ideally this should be somewhat location-based for some types of searches.

(4) Playing games. You’re sitting around for a few minutes killing time, and you want a way to pass that time.

Some things that sound like they should fall into one category really fall into another: surfing the ‘net on the iPhone, for example, strikes me as an activity similar to playing games–a way to kill time. Other activities may also sort of fall into multiple categories: for example, if you search for a movie theater to see what’s playing, is further followups to that theater a ‘search’ activity or a ‘status’ activity? (In other words, would you want to revisit the movie theater to see what’s playing on a different day, or do you want to be alerted 20 minutes before a movie at that theater starts so you remember to wander back to catch the movie?)

I think one of the mistakes people are making with respect to the phone is that they are treating it as a desktop computer, rather than as a sophisticated communications device. More than once I’ve seen people try to suggest the iPhone become an ‘immersive’ environment. How immersive can a 5″ diagonal screen be?

A detached table delegate must be referred in the NIB

Here’s a puzzling problem I just encountered a third time, and wasted a better part of the morning sorting out, which I had solved before but forgot to record my solution.

On the iPhone, I wanted to create an object which serves as a delegate to a UITableView. This object is then instantiated in the NIB file alongside the UIViewController which owns the control on which the UITableView lives. So I created an instance, and pointed the delegate and dataSource references of the UITableView at my table controller object.

On startup, my iPhone application crashed.

The solution appears to be creating a reference to my object from the owner of the NIB.

My mental model as to how a NIB is loaded on the phone is that every object is instantiated and initialized, then events are fired to begin populating things like the contents of the table. In other words, objects are loaded then events fired. What appears to be going on, however, is that objects are loaded then initialized in an order-dependent fashion which I don’t completely understand–however, by creating a reference from the owner to the delegate object (which is after the table item), the delegate object and the table object are loaded and initialized in the correct order.

So the lesson appears to have the owner object hold references to both the table (indirectly via the view containing the table) and the delegate object which controls the table.

OpenGL Fog: the z component is at the model transformation.

When dealing with fog, the z distance used to compute the fog density. However, which z?

Turns out, the z depth used is the z depth that is computed after applying the GL_MODELVIEW matrix but before applying the GL_PROJECTION matrix. One result of this is that through the careful manipulation of both matrixes you can create the effect of fog on the valley floor below the viewpoint: fog doesn’t just have to be haze in the distance.

Design is How Things Work

How Design Can Save Democracy

It’s an interesting series of articles and the New York Times interactive feature is well worth browsing. And the problems they address are also relevant to web site design and to application development: by clearly segregating instruction from function (in this case, how to fill in the ballot from the ballot bubbles themselves), it makes figuring out the ballot easy and fast.

Software Development Tools

Many years ago I got a DSL connection with a fixed IP address. I paid a fortune per month to run that fixed IP address, but the nice thing was being able to put my server on-line so I could run my own e-mail server, my own web server, and my own source control system.

A couple of months ago I switched to a new ISP which was cheaper–but I gave up the fixed IP addresses in the process.

On the other hand, there is no need for having my own IP address when for less money I can sign up for the following services:

Google Apps: Free e-mail and shared documents.

SVN Hosting: I am using the $7/month level service at SVNRepository.com; this gives me theoretically unlimited repositories and users and a 2gig storage cap.

Web Hosting: I’m using the $7/month level basic service at LunarPages.com; I can park all of my different web sites on the same account (and even host different page collections from one account), and for an extra $2/month they’ll also host my JSP pages.

So I’m out $16/month on the above services–but the fixed IP address was running me $30/month, and it required me to maintain a separate computer, constantly update and maintain the software there. I don’t know how secure SVNRepository is: if I’m running something mission critical or creating software worth hundreds of millions of dollars I’d probably run my own SVN server. But for synchronizing my code across three different computers and providing me the ability to share code bases with other people, it’s pretty damned cool.

And so a new chapter begins for our plucky hero.

The application checklist for applying to graduate school includes the following:

  1. A completed application form.
  2. A Statement of Purpose
  3. At least 3 letters of recommendation.
  4. Additional information, such as abstracts, resume, list of publications, etc. Essentially a CV or the work equivalent.
  5. GRE test scores.

I’ve completed #5 in the list above. I have until December 15th (realistically, December 1) to complete the rest. (And I got an 800/610–respectable, though I thought I could do better on the verbal. But in a test environment, you choke–and I choked hard. Assuming the essay portion of the test went well, I think it’s good enough.)

If all goes well, then by next spring I should hear from one of the three schools I’m applying at: either Caltech, USC or UCLA. And if this all works out as I hope, then I will be entering the Ph.D program in Computer Science.

Why a Computer Science Ph.D.? Because I promised myself 20 years ago when I left college that someday I would go back and get a higher degree. And now is the time to complete that promise.

Updated ASN.1 Library

Well, I got an interesting correspondence yesterday and a follow-up today–and in investigating I realized that there were some primitives in my ASN.1 BER library which I failed to handle back when I wrote this two years ago.

Originally I wrote the library because I was interested in building my own LDAP engine. I had written parts of an engine, but I “borrowed” the Netscape LDAP library’s BER tag parsing code to handle incoming and outgoing messages. But the LDAP library wasn’t mine, nor was it robust, so I set out to write a replacement.

The problem was when I got enough to parse LDAP, I considered my replacement done. And it wasn’t. Far from it.

It turns out there are a couple of other primitive types that have been introduced elsewhere: RFC 3641 defines a couple of new constructs, and it turns out I completely skipped one of the primitives, the relative OID type, when I originally built my library.

I’ve corrected the problems, and uploaded a new version of the library, though the new types aren’t very well tested at this point.

Update: After spending the past few months writing Objective C++ code, it felt good to blow the dust off my mad Java sk|11z.

Update 2: Did I mention Fatih Batuk’s Java ASN.1 Compiler that uses my library? Go check it out.