Aug 282009
 

Solid State Disks (SSD) are the future! I hereby declare that if you own equities in Western Digital, Seagate or any other platter based hard disk company, you better sell it quick because they are in trouble!

The hard disk market has been the last remaining bastion of “new old-tech” that has not seen true revolution since the dawn of modern computers. By far, it is the slowest and the least reliable part of a computer. When I buy a computer, I know that I will more than likely end up having to replace the hard drive.

My new technology obsession is the SSD. The price has come down to a point where a mortal enthusiast can afford one now for a mere price of a leg (not the two like it used to be). With Snow Leopard being released, I decided to take my new SSD for a spin. The undisputed king of SSDs at the moment is the Intel X-25M. The second generation (G2) came out not too long ago. With absolutely no moving parts, zero seek time and insane random read/write speeds, this thing just screams along. Here are some videos.

Please excuse the shaky camera work and the horrible video quality. I was using my left hand to record (I’m right handed) and the video is from an old, antiquated digital camera that’s just teetering on death.

For the first video. I went into the Applications folder, selected bunch of applications, and opened them up all at once at the same time. This is a new video I made with Quicktime X’s screen recording feature — new in Snow Leopard. I felt compelled to make a new presentable video after getting way too many complaints about the horrible quality of the first video.

The second video shows me opening Adobe Photoshop, Illustrator and SoundBooth at once at the same time. If I had done this on a normal HDD, the HDD would have thrashed into tomorrow.

The third video shows boot time from a completely shut down state. The timer starts as soon as I press the power button. The stop watch is hard to see due to the darkness and my crappy camera, but you can catch a glimpse of the final time towards the end of the video. For this video, I made a makeshift tripod out of my chair a coffee table after receiving complaints about motion sickness.

The final two videos shows the boot up and program start up time from my old HDD. It’s painfully slow.

Program start up video from a regular hard disk.

I’m Sold!
After having only used this for a day, I can conclusively say that I don’t think I will ever go back to normal hard disks again. I believe that SSD is a revolutionary advancement in hard drive technology. When it comes to user interface performance, responsiveness (snappiness) and perception is everything. The number of IO operations per second this SSD can handle is impressive. It doesn’t matter what I throw at it, programs just load up in an instant.

 Posted by at 1:22 pm
Aug 262009
 

More likely than not, your application will have crashed at some point in its development cycle. And you will have seen a cryptic message like this on the console.

2009-08-19 13:45:19.059 TestApp[3905:20b] Stack: (
2478641131,
2426342971,
2478670314,
2478663660,
2478663858,
92386,
816691521,
816216343,
816148479,
816144864,
827743722,
827753484,
2478142405,
2478144168,
827745792,
827745989,
816114848,
816160924,
9656,
9510
)

The problem is that you have no idea where in the code the crash is happening. Java’s stack trace is very descriptive, with function names and line numbers. This is also possible in XCode, but you have to take an extra step.

Run your iPhone application and then wait for it to crash, displaying the stack trace as above. The program will have paused at this point. If you go down to the console, you’ll see a prompt that says (gdb), where you can type in gdb commands.

Look at the stack trace above, and try to find a small number somewhere in the middle of the stack. This is likely where your program crashed. In the example above, this number is 92386. Once you have identified this number, you can now identify more helpful information about the crash.

Issuing the command: info symbol 92386

Will give you something like this:
-[MainViewController touchesEnded:withEvent:] + 164 in section LC_SEGMENT.__TEXT.__text of /Users/Min/Library/Application Support/iPhone Simulator/User/Applications/877EB45A-AB6B-4CD5-AA43-C7B0F2C98F7B/TestApp.app/TestApp

Issuing the command: info line *92386
Will you give something like this:

Line 416 of "/Users/Min/Documents/Projects/TestApp/Classes/MainViewController.m" starts at address 0x168b5 <-[MainViewController touchesEnded:withEvent:]+119> and ends at 0x16985 <-[MainViewController touchesEnded:withEvent:]+327>

So there you have it. You now know that the crash took place in the [MainViewController touchedEnd:withEvent:] message on line 416.

Aug 242009
 

Proper use of threads will do wonders for your program’s responsiveness. It will also do wonders in making your code harder to follow. What if you have a thread churning along in the background and you’d like to know when that thread has produced a value before continuing on with your work? Maybe you have a thread called ComputeWinningStockThread that takes all the data from the stock market, applies some magic formula and spits out stocks that are going to make you millions in random time intervals.

1. Start ComputeWinningStockThread in background.
2. Until ComputeWinningStockThread has picked a stock, continue checking to see if it has.

This is the poor man’s version. It is also called the busy loop or polling. And it uses up valuable resources that your iPhone could be using for other things.

The proper way to handle this is with the NSConditionLock. You can use NSConditionLock to have one thread wait for notification from another thread before continuing. Or, in other words, it blocks until a condition is met (hence, the name conditional lock).

In Objective-C, this is the gist of what you would have to do.

- (void) ComputeWinningStockThread {
    while (YES) {
        [myLock lock];
        winningStock = [self someSecretAlgorithm];        
        [myLock unlockWithCondition:0];
    }
}

Then maybe in another message, you are calling this thread to earn your millions.

NSConditionLock *myLock = [[NSConditionLock alloc] initWithCondition:0];
[NSThread detachNewThreadSelector:@selector(ComputeWinningStockThread) toTarget:self withObject:nil];

// This will block until it is unlocked in the thread
[myLock lockWhenCondition:1];
NSLog(@"I have a winning stock! %@", winningStock);
 Posted by at 12:59 pm
Aug 202009
 

Predicting user behavior on the iPhone is difficult. One can never know how many pages of Safari someone might have in the background hogging up valuable resources. Every now and then, I get reports of our application crashing for no apparent reason. More often than not, it’s caused by the phone running low on memory. It’s amazing how little memory we have to work with on the iPhone. With Safari taking up 8 pages in the background, our application was crashing at mere 8 MB of memory usage.

Load Late and Lazily

Sometimes you have to sacrifice the snappy UI for a low memory footprint. It’s better than your application crashing. This means never preloading resources but waiting until the moment you need it. If your XIB (NIB) file has a lot of views, try separating them into multiple NIB files so that you can load it individually when you need it. When a view is not visible, the system will free it from memory.

- (void) didReceiveMemoryWarning

The didReceiveMemoryWarning message will be called when the iPhone is running low on memory. It is highly recommended that you override this message in all your view controllers and print out a simple debug message in it. Also, do not forget to call [super didReceiveMemoryWarning].

- (void) setView:(UIView*) view

If you receive the didReceiveMemoryWarning message, the setView message will be called with a nil parameter. It will be called to release the view if the view is not the active view. This is where you will want to release as much resources as you can, such as all your IBOutlet variables. Also, do not forget to call [super setView:view] or your application will crash.

Initialization

Once your view is freed, the NIB will be read back into memory when it is needed. This means the viewDidLoad message will be called again. So take care not to place initialization code that should only be initialized once per application in that message.

CLANG Analyzer

If you haven’t tried this tool already, then you are truly missing out. Check out this extremely helpful post by Jeff Lamarche, the author of Beginning iPhone Development. CLANG will analyze your code and give you a detailed report of problems your code may have, including memory leaks.

Also, If you’ve missed my previous post about the dangers of UIImage, you can check it out here.

 Posted by at 8:22 pm