[Objective-C + Cocoa] Runtime Performance Profiling

The iPhone SDK and XCode provide some very useful tools for application profiling, particularly with respect to tracking memory consumption and pinpointing memory leaks and other similar issues, but one thing which I have found lacking in the default toolset is the ability to track the execution time of this-or-that specific bit of code, be it a function call, a loop within a function, or some arbitrary series of API calls made in quick succession.

Typically I would deal with such cases by adding some one-off code around the section that I was interested in profiling to measure and log its execution time. But this approach quickly becomes unwieldy when there are several different places that you are interested in profiling, and particularly when it comes time to track down and remove all of these bits of code so that they stop spamming the log with timing data that is no longer needed.

In any case, here is my solution to this minor annoyance, patterned after a similar utility I implemented in ActionScript some time ago:

//PerformanceTimer.h
#import <Foundation/Foundation.h>


@interface PerformanceTimer : NSObject {
    NSMutableArray* startTimes;
    NSMutableArray* names;
}

+ (void) startTimerWithName: (NSString*) name;
+ (clock_t) stopLastTimer;
+ (clock_t) stopTimerWithName: (NSString*) name;

@end


//PerformanceTimer.m
#import "PerformanceTimer.h"

static PerformanceTimer* timerInstance = nil;

@implementation PerformanceTimer

- (id) init {
    self = [super init];
    if (self) {
        startTimes = [[NSMutableArray alloc] initWithCapacity:16];
        names = [[NSMutableArray alloc] initWithCapacity:16];
    }
    
    return self;
}

- (void) dealloc {
    [startTimes release];
    startTimes = nil;
    
    [names release];
    names = nil;
    
    [super dealloc];
}

- (void) startTimer: (NSString*) name {
    @synchronized(startTimes) {
        clock_t start = clock();
        NSNumber* startNum = [NSNumber numberWithUnsignedLong:start];
        [startTimes addObject:startNum];
        [names addObject:name];
    }
}

- (clock_t) stopTimerNamed: (NSString*) name {
    @synchronized(startTimes) {
        int index = 0;
        for (NSString* timerName in names) {
            if ([timerName isEqualToString:name]) {
                break;
            }
            index++;
        }
        if (index >= [names count]) {
            //couldn't find it
            return 0;
        }
        clock_t start = [[startTimes objectAtIndex:index] unsignedLongValue];
        clock_t end = (clock() - start) / (CLOCKS_PER_SEC / 1000.0);
        
        #ifdef DEBUG
        //if debugging, always print, otherwise let the caller decide what to do
        NSLog(@"PerformanceTimer:  Total execution time for task named '%@':  %lu ms", name, end);
        #endif
        
        [startTimes removeObjectAtIndex:index];
        [names removeObjectAtIndex:index];
        
        return end;
    }
}

- (clock_t) stopTimer {
    @synchronized(startTimes) {
        if ([names count] < 1) {
            //no timer is running
            return 0;
        }
        
        NSString* name = [names objectAtIndex:[names count] - 1];
        return [self stopTimerNamed:name];
    }
}

+ (void) startTimerWithName: (NSString*) name {
    if (! timerInstance) {
        timerInstance = [[PerformanceTimer alloc] init];
    }
    [timerInstance startTimer:name];
}

+ (clock_t) stopLastTimer {
    if (! timerInstance) {
        timerInstance = [[PerformanceTimer alloc] init];
    }
    return [timerInstance stopTimer];
}

+ (clock_t) stopTimerWithName: (NSString*) name {
    if (! timerInstance) {
        timerInstance = [[PerformanceTimer alloc] init];
    }
    return [timerInstance stopTimerNamed:name];
}

@end

This adds a static utility class that can be used to spawn multiple independent named timers. It is used like:

[PerformanceTimer startTimer:@"myTimerName"];
//do some things that you want to time
clock_t elapsedTimeMillis = [PerformanceTimer stopTimerWithName: @"myTimerName"];
//print or log the elapsed time

The default behavior of this class when run in debug mode is to print out the elapsed time automatically when ‘stopTimer’ is called, so it’s not generally necessary to capture or inspect the value returned from ‘stopTimer’ unless you are either running in release mode or if you want to do something more involved than simply logging the timing data to the console.

Note that although a ‘stopLastTimer’ method is provided for convenience, its use is generally not recommended unless you are absolutely sure that nobody else has started a timer somewhere else in the code. Otherwise you can end up inadvertently stopping the wrong timer. Inside of a small, simple, single-threaded application there is little to worry about. But for any more complex/multi-threaded projects it is much safer to always specify a timer by name.

Posted in coding, objective-c | Tagged , , | 1 Comment

[Objective-C + Cocoa] Screen Capture, Multiplexing, and More

It’s been a bit quiet on the coding-front lately, so I thought I’d share a small handful of various utilities that I’ve developed over the past few weeks. None of them are particularly revolutionary, but they can certainly prove useful in the right situations. Anyways, in no particular order, I give you:

ScreenCaptureView

This bit of code allows you to easily capture the contents of any arbitrary UIView:

//  ScreenCaptureView.h
#import <UIKit/UIKit.h>

@interface ScreenCaptureView : UIView {
}

@property(retain) UIImage* currentScreen;
@property(assign) float frameRate;

@end


//  ScreenCaptureView.m
#import "ScreenCaptureView.h"
#import <QuartzCore/QuartzCore.h>

@implementation ScreenCaptureView

@synthesize currentScreen, frameRate;

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        self.contentMode = UIViewContentModeRedraw;
        self.frameRate = 20.0f;//20 frames per seconds
    }
    return self;
}

- (void) drawRect:(CGRect)rect {
    CGContextRef context =  UIGraphicsGetCurrentContext();
    [self.layer renderInContext:context];
    CGImageRef cgImage = CGBitmapContextCreateImage(context);
    UIImage* background = [UIImage imageWithCGImage: cgImage];
    CGImageRelease(cgImage);
    self.currentScreen = background;
    
    [self performSelector:@selector(setNeedsDisplay) withObject:nil afterDelay:(1.0 / self.frameRate)];   //redraw at the specified framerate
}

- (void)dealloc {
    [super dealloc];
}
@end

The ‘ScreenCaptureView‘ class automatically captures its current contents (including any nested subviews) to a UIImage which it exposes through the ‘currentScreen‘ property. You can use this functionality to do things like generate screenshots of your application for use in help/tutorial (or promotional) content, and you can even pass the data as frames to an `AVCaptureSession` to create a live video of your app in action.

Update: An enhanced version of this class that includes the ability to record video is now available.

MultiplexingDelegate

For those rare cases when you want multiple delegate objects to be notified of a change/event in some object:

//  MultiplexingDelegate.h
#import <Foundation/Foundation.h>

@interface MultiplexingDelegate : NSObject {
    NSMutableArray* delegates;
}

- (void) addDelegate: (id) theDelegate;
- (void) removeDelegate: (id) theDelegate;
- (void) sendSelectorToDelegates: (SEL)selector withObject: (id)param1 andSecondObject: (id)param2
@end

//  MultiplexingDelegate.m
@implementation MultiplexingDelegate
- (id) init {
    if ((self = [super init])) {
        delegates = [[NSMutableArray alloc] initWithCapacity: 16];
    }
}

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

- (void) addDelegate: (id) theDelegate {
    @synchronized(delegates) {
        if (theDelegate && ! [delegates containsObject: theDelegate]) {
            [delegates addObject: theDelegate];
        }
    }
}

- (void) removeDelegate: (id) theDelegate {
    @synchronized(delegates) {
        if (theDelegate && [delegates containsObject: theDelegate]) {
            [delegates removeObject: theDelegate];
        }
    }
}

- (void) sendSelectorToDelegates: (SEL)selector withObject: (id)param1 andSecondObject: (id)param2 {
    @synchronized(delegates) {
        for (id theDelegate in delegates) {
            if (param2) {
                [theDelegate performSelector:selector withObject:param1 withObject:param2];
            }
            else if (param1) {
                [theDelegate performSelector:selector withObject:param1];
            }
            else {
                [theDelegate performSelector:selector];
            }
        }
    }
}
@end

The ‘MultiplexingDelegate` class provides a generic starting point for creating delegates that conform to various protocols and support the multiplexing of events to any number of attached listeners. To use it you just need to create a new subclass of ‘MultiplexingDelegate‘ that implements whatever protocol you are interested in. For instance, here is a partial example of a multiplexing UISearchBarDelegate implementation:

//  MultiplexingSearchBarDelegate.h
#import <UIKit/UIKit.h>
#import "MultiplexingDelegate.h"

@interface MultiplexingSearchBarDelegate : MultiplexingDelegate<UISearchBarDelegate> {
}
@end

//  MultiplexingSearchBarDelegate.m
@implementation MultiplexingSearchBarDelegate
//add UISearchBarDelegate methods here, following a pattern like this:
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
    [self sendSelectorToDelegates: @selector(searchBar:textDidChange:) withObject: searchBar andSecondObject: searchText];
}

//or alternately/equivalently, a pattern like this:
- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    @synchronized(delegates) {
        for (id<UISearchBarDelegate> theDelegate in delegates) {
            [theDelegate searchBar:searchBar shouldChangeTextInRange: range replacementText: text];
        }
    }
}
@end

To use the ‘MultiplexingSearchBarDelegate‘ class you would create a single instance and add it as the delegate of your UISearchBar. Then you just register every other object that you want to receive UISearchBar events with the ‘MultiplexingSearchBarDelegate‘ (by using the ‘addDelegate:‘ method), and they will all receive event notifications from the UISearchBar. Simple, but powerful.

NSString+JavaAPI

There’s no getting around it, the standard NSString API just kind of sucks. Wouldn’t it be great if NSString supported an API that was more like what Java provides through its String class? Well now it can:

//  NSString+JavaAPI.h
#import <Foundation/Foundation.h>

@interface NSString (NSString_JavaAPI)
- (int) compareTo: (NSString*) comp;
- (int) compareToIgnoreCase: (NSString*) comp;
- (bool) contains: (NSString*) substring;
- (bool) endsWith: (NSString*) substring;
- (bool) startsWith: (NSString*) substring;
- (int) indexOf: (NSString*) substring;
- (int) indexOf:(NSString *)substring startingFrom: (int) index;
- (int) lastIndexOf: (NSString*) substring;
- (int) lastIndexOf:(NSString *)substring startingFrom: (int) index;
- (NSString*) substringFromIndex:(int)from toIndex: (int) to;
- (NSString*) trim;
- (NSArray*) split: (NSString*) token;
- (NSString*) replace: (NSString*) target withString: (NSString*) replacement;
- (NSArray*) split: (NSString*) token limit: (int) maxResults;
@end

//  NSString+JavaAPI.m
#import "NSString+JavaAPI.h"

@implementation NSString (NSString_JavaAPI)
- (int) compareTo: (NSString*) comp {
    NSComparisonResult result = [self compare:comp];
    if (result == NSOrderedSame) {
        return 0;
    }
    return result == NSOrderedAscending ? -1 : 1;
}

- (int) compareToIgnoreCase: (NSString*) comp {
    return [[self lowercaseString] compareTo:[comp lowercaseString]];
}

- (bool) contains: (NSString*) substring {
    NSRange range = [self rangeOfString:substring];
    return range.location != NSNotFound;
}

- (bool) endsWith: (NSString*) substring {
    NSRange range = [self rangeOfString:substring];
    return range.location == [self length] - [substring length];
}

- (bool) startsWith: (NSString*) substring {
    NSRange range = [self rangeOfString:substring];
    return range.location == 0;
}

- (int) indexOf: (NSString*) substring {
    NSRange range = [self rangeOfString:substring];
    return range.location == NSNotFound ? -1 : range.location;
}

- (int) indexOf:(NSString *)substring startingFrom: (int) index {
    NSString* test = [self substringFromIndex:index];
    return [test indexOf:substring];
}

- (int) lastIndexOf: (NSString*) substring {
    if (! [self contains:substring]) {
        return -1;
    }
    int matchIndex = 0;
    NSString* test = self;
    while ([test contains:substring]) {
        if (matchIndex > 0) {
            matchIndex += [substring length];
        }
        matchIndex += [test indexOf:substring];
        test = [test substringFromIndex: [test indexOf:substring] + [substring length]];
    }
    
    return matchIndex;
}

- (int) lastIndexOf:(NSString *)substring startingFrom: (int) index {
    NSString* test = [self substringFromIndex:index];
    return [test lastIndexOf:substring];
}

- (NSString*) substringFromIndex:(int)from toIndex: (int) to {
    NSRange range;
    range.location = from;
    range.length = to - from;
    return [self substringWithRange: range];
}

- (NSString*) trim {
    return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (NSArray*) split: (NSString*) token {
    return [self split:token limit:0];
}

- (NSArray*) split: (NSString*) token limit: (int) maxResults {
    NSMutableArray* result = [NSMutableArray arrayWithCapacity: 8];
    NSString* buffer = self;
    while ([buffer contains:token]) {
        if (maxResults > 0 && [result count] == maxResults - 1) {
            break;
        }
        int matchIndex = [buffer indexOf:token];
        NSString* nextPart = [buffer substringFromIndex:0 toIndex:matchIndex];
        buffer = [buffer substringFromIndex:matchIndex + [token length]];
        if (nextPart) {
            [result addObject:nextPart];
        }
    }
    if ([buffer length] > 0) {
        [result addObject:buffer];
    }
    
    return result;
}

- (NSString*) replace: (NSString*) target withString: (NSString*) replacement {
    return [self stringByReplacingOccurrencesOfString:target withString:replacement];
}
@end

Note that this isn’t the complete Java String API (and also that `split()` does not support regular-expressions as it does in Java). It is just a subset consisting of the most useful Java API functions that do not have convenient analogs in the standard NSString API. Still, it makes a lot of common string manipulations a lot more straightforward than they otherwise would be.

Posted in coding, objective-c | Tagged , , , | 16 Comments

Introducing Webcomix

I wanted to take a brief moment to invite anyone who stumbles across this post to beta-test my latest personal project; Webcomix. Webcomix is a simple web-comic aggregation service that allows you to read a number of different comics on a single page. Here is a screenshot of it in action:

Webcomix screenshot

Each comic in Webcomix is periodically checked for updates, so if like me you keep tabs on several different web-comics that all update at different intervals then Webcomix will save you from having to remember to refresh half a dozen different websites at various times just to keep up to date. Simply visit your Webcomix dashboard and you’re set!

Underneath the covers there’s a fair bit that I’m proud of with this app. First off the entire system is designed to be as lightweight and efficient (in terms of server compute-time and bandwidth) as reasonably possible. Virtually all of the actual work is handled by the client-side JavaScript. The handful of tasks that must be performed server-side are optimized with the help of a custom caching layer which ensures that any given computation (or fetch of an external resource) only needs to be performed once. There is also an additional caching layer in the client used to prevent it from making any given request to the server more than once per session.

The server itself is client-agnostic and provides a simple JSON-based API, meaning that while the initial incarnation of Webcomix is in the form of a web-app it should be just as easy to package the same functionality in a mobile, desktop, or other flavor of application. But that’s a project for another day.

Anyhow, please note that Webcomix should be considered to be beta software at the moment. So if you find any bugs or have any suggestions for new features or improved functionality then please don’t hesitate to say so in the comments section.

Also, the list of comics currently available in Webcomix is not set in stone and is only based upon my personal preferences at the moment. Webcomix is designed in a way that makes adding additional comics a trivial task, so if your favorite comic is currently not in the list then I encourage you to post a request in the comments section so that I can add it.

Lastly, if anyone has any good ideas for how to extend the comic selection UI to handle a large number of comics that they’d like to share, then please do. The current interface with its basic rows of checkboxes is obviously not sufficient for handling hundreds (or even dozens) of comics. It needs to be replaced with something better (or at least, collapsible) soon.

Posted in banter, javascript, software | Tagged , , | Leave a comment

[Hardware] Intel Atom D510 Server Build

As mentioned awhile back, the aging server box that was being used to host this blog started to develop some stability issues and I decided to replace it with an Intel Atom based machine. After nearly a month spent waiting for some back-ordered parts to arrive the build is finally complete. So how does it compare to the system it replaced? Well first off, let’s talk specs. The Atom D510 build used the following components:

Here’s a shot of everything unboxed and ready to be assembled:

Atom D510 Build Components

And here’s one of the build with everything installed and ready to be shut away inside of the case:

Completed Build

All told the total cost of this build was just slightly under AU$400, including GST and shipping fees. Nearly half of this was allocated to the Corsair SSD, so a comparable build may be attainable for closer to $300 if you’re willing to settle for a traditional HDD. As this system was intended to do duty as a server box, however, I felt that the performance benefit provided by the SSD was more than worth the extra cost.

Anyways, the system being replaced by the Atom build is a retail Hewlett-Packard box that was purchased way back in 2001. It has the following specs:

  • 1.3 GHz Intel Pentium 4 (no HyperThreading)
  • 256 MB PC-800 (400MHz) RDRAM
  • 40 GB Western Digital HDD (IDE)
  • Stock motherboard, case, audio, etc.

This system is all but worthless today, but back in 2001 it retailed for close to $1100 (with bundled monitor and printer). In its defense this old P4 box delivered a solid decade’s worth of performance and proved itself to be entirely capable of running a number of different servers, albeit under very light workloads. But all things must come to an end, and it’s time for this dinosaur to be replaced.

So how does the Atom processor stack up against this 10-year-old beast? Here’s a screenshot from Super PI comparing the two (the Atom is on the left, and the P4 is on the right):

SuperPI:  Atom D510 (left) vs. 1.3 GHz P4 (right)

Now it’s worth noting that this is not and cannot be an apples-to-apples comparison between the two CPU’s, as all the other variables (RAM capacity and speed, disk architecture, etc.) have been changed as well. But I think Super PI probably does a fairly good job of isolating the CPU, and at the 1M setting the task should be small enough that the difference in RAM capacity between the two systems doesn’t come into play.

Assuming that to be the case, the Atom D510 makes a fairly strong showing for itself. It comes in at roughly 3 times faster than the 1.3 GHz P4, and since the Atom D510 is a dual-core CPU one should expect it to be up to 6 times faster under a well-threaded (i.e. server) workload. That’s quite an improvement over the old system, although it’s worth noting that my desktop system (an Intel Core 2 Quad based machine clocked at 3.5 GHz) can breeze through the same benchmark in just under 15 seconds. So by modern standards the Atom CPU is quite slow.

But sheer performance is only part of the story. The other reason why I opted for the Atom based server is the Atom platform’s low power consumption. If I wanted the fastest server possible I could simply use my desktop for the task, and leave it running 24/7. And then I would cringe every time my utility bill was due. With the Atom my goal was to attain reasonable performance using as little power as possible, and after looking at the numbers I can only conclude that it delivers as advertised.

Using a Kill-A-Watt device I measured the power consumption of each system at the wall, and worked out that the 10-year-old P4 system draws 90 watts of power while sitting idle, and around 110 watts under full CPU load. The Atom system, on the other hand, weighs in at 17 watts while idle, and a massive 21 watts under full CPU load.

So 6 times the performance, for less than 1/5th the power consumption (and before I forget, the Atom system is virtually silent as well). With those numbers the Atom system starts to look like 100% win. I can run one box and get much better performance than the old system could deliver at a fraction of the energy consumption, or I could use the same amount of power to run a cluster of 5 Atom servers for 30 times the performance.

But in any case, that’s my Atom server build, and overall I’m quite pleased with the results. The Atom D510 provides a nice bump in speed over the (admittedly decrepit) server box that it replaced, while also using much less power. If you need a cheap, basic, quiet server box for low-volume workloads then an Atom-based solution is an option worth considering.

Posted in configuration, hardware | Tagged , | 3 Comments

[JavaScript + CSS] Fun with Google Maps

Here are a couple of quick Google Maps hacks that I came up with quite awhile ago; several years ago, in fact. While not hugely useful or profound, they do expose some fairly large holes in the Google Maps API. Holes that I would have expected a company like Google to have patched up by now.

First, let’s say that for whatever reason you need to remove the “Powered by Google” logo and the other copyright and similar boilerplate that normally appears along the bottom of the map. Why would you want to do this? Perhaps because you are displaying your map inside of a small area of the page where space is constrained to the point that the logo and other things are adding too much noise. Or perhaps because you feel (quite justifiably) that Google Maps have become iconic to the point that nobody needs to see a “Powered by Google” logo in the corner to know that the map is being powered by Google.

Whatever your reason for wanting to unclutter the map’s footer section, the task can be accomplished using a smidgen of CSS:

		.terms-of-use-link {
		    display: none;
		}

		#myMapContainerId div span {
			display: none;
		}

…and a handful of JavaScript:

			//call this after setting up your GMap2 instance
			window.unclutter = function() {
				var executed = false;
				var images = document.getElementsByTagName('img');
				for (var index = 0; index < images.length; index++) {
					var node = images[index];
					if (node.src && node.src.indexOf("mapfiles/poweredby.png") > 0) {
						node.style.display = 'none';
						executed = true;
					}
				}

				if (! executed) {
					setTimeout(window.unclutter, 250);
				}
			};

It’s pretty straightforward, really. The CSS gets rid of the “Terms of Use” link, as well as the spans that are used to display copyright text (note that you should replace the ‘myMapContainerId‘ with whatever your actual map div-id is). The JavaScript is used to get rid of the “Powered by Google” logo, which is added to the map after it loads. To use this code, you just need to call ‘unclutter()‘ after setting up your Google Map instance.

Of course, doing this is a blatant violation of the Google Maps Terms of Service. You know, the terms Google made you agree to when you generated your API key. Whether or not there is any merit in having Terms of Service mandate things which do nothing whatsoever to benefit end users such as the display of logos and copyright gibberish is a topic for another day. The topic for today is, if Google Maps can be used without an API key, and hence without agreeing to the Terms of Service, what does it matter what the terms are anyways?

That’s right, the Google Maps API can be used, at least for basic tasks, completely without an API key. It’s quite simple really, just a tiny bit more JavaScript:

			//be sure to do this *before* you source in the Google Maps javascript
			window._alert = window.alert;
			window.alert = function() {return;};

…and then you can include the Google Maps JavaScript without specifying an API key, like so:

<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=true" type="text/javascript"></script>

The added JavaScript simply moves the browser’s built-in ‘alert()‘ function to ‘_alert()‘ so that the map can’t use it to display a message complaining about the missing API key. For whatever reason, apart from this alert message Google does nothing to prevent their API from being used without a valid key. So by simply suppressing the error message you can get a fully functional Google map without registering for a key or agreeing to the Terms of Service.

Put all of this together and you can get an anonymous, unbranded, uncluttered map the works just as well as the original version. The source code (verified in current versions of IE, Firefox, and Chrome) might look something like this:

<html>
	<head>
		<title>Google Maps API Example Hack</title>
		<style>
			.terms-of-use-link {
		    		display: none;
			}

			#myMapContainerId div span {
			     display: none;
			}
		</style>
		<script type="text/javascript">
			window._alert = window.alert;
			window.alert = function() {return;};

			window.setupMap = function() {
				window.map = new GMap2(document.getElementById("myMapContainerId"));
				map.setCenter(new GLatLng(37.4419, -122.1419), 13);
				map.addControl(new GLargeMapControl3D());
				map.addControl(new GMapTypeControl());
			};

			window.unclutter = function() {
				var executed = false;
				var images = document.getElementsByTagName('img');
				for (var index = 0; index < images.length; index++) {
					var node = images[index];
					if (node.src && node.src.indexOf("mapfiles/poweredby.png") > 0) {
						node.style.display = 'none';
						executed = true;
					}
				}

				if (! executed) {
					setTimeout(window.unclutter, 250);
				}
			};

			window.onload = function() {setupMap(); unclutter();};
		</script>
		<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=true&amp;" type="text/javascript"></script>
	</head>
	<body>
		Note the lack of branding/logos, terms of use links, and copyright footer text in the map below.<br />
		Also note the lack of any Google Maps API key in the document source.<br />
		And the lack of any annoying <a href="#" onclick="_alert('I can still create alerts, but the Google Map can\'t.'); return false;">alert</a> popups complaining about the API key.<br /><br />
		<div id="myMapContainerId" style="width: 600px; height: 400px;"></div>
	</body>
</html>

…which gives you a page like this one. It’s enough to make one wonder why anyone would bother signing up for a Google Maps API key the proper way, when the entire thing can be subverted so easily.

Posted in coding, javascript | Tagged , , | 2 Comments

[Status] Upgrade Complete

Finally all the parts arrived, and the build and migration process was completed without incident. This site is now hosted on a shiny new energy-efficient Atom D510 based server box. More details on the hardware and the build and configuration process later.

Posted in status | Leave a comment

[Cocoa + iPhone] Avoiding ‘_handleMemoryWarning:’ Crashes

Spend enough time developing iPhone applications (particularly if you go to the trouble of collecting crash logs from your apps), and eventually you are bound to come across something like the following:

2011-03-04 14:17:48.872 myApp[15129:307] -[UIImageView _handleMemoryWarning:]: unrecognized selector sent to instance 0x2b2060
[Switching to process 11523 thread 0x0]
2011-03-04 14:17:57.034 myApp[15129:307] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIImageView _handleMemoryWarning:]: unrecognized selector sent to instance 0x2b2060'
*** Call stack at first throw:
(
	0   CoreFoundation                      0x3759dc7b __exceptionPreprocess + 114
	1   libobjc.A.dylib                     0x32d9bee8 objc_exception_throw + 40
	2   CoreFoundation                      0x3759f3e3 -[NSObject(NSObject) doesNotRecognizeSelector:] + 98
	3   CoreFoundation                      0x37544467 ___forwarding___ + 506
	4   CoreFoundation                      0x37544220 _CF_forwarding_prep_0 + 48
	5   Foundation                          0x351663b5 _nsnote_callback + 156
	6   CoreFoundation                      0x37520971 __CFXNotificationPost_old + 396
	7   CoreFoundation                      0x37520611 _CFXNotificationPostNotification + 128
	8   Foundation                          0x351556a3 -[NSNotificationCenter postNotificationName:object:userInfo:] + 70
	9   Foundation                          0x3515edbd -[NSNotificationCenter postNotificationName:object:] + 20
	10  UIKit                               0x35a32354 -[UIApplication _performMemoryWarning] + 68
	11  UIKit                               0x35a33450 -[UIApplication _receivedMemoryNotification] + 184
	12  UIKit                               0x35a2ef24 _memoryStatusChanged + 64
	13  CoreFoundation                      0x37552333 __CFNotificationCenterDarwinCallBack + 26
	14  CoreFoundation                      0x37537e37 __CFMachPortPerform + 218
	15  CoreFoundation                      0x3752f5cb __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 28
	16  CoreFoundation                      0x3752f589 __CFRunLoopDoSource1 + 164
	17  CoreFoundation                      0x37521835 __CFRunLoopRun + 580
	18  CoreFoundation                      0x3752150b CFRunLoopRunSpecific + 226
	19  CoreFoundation                      0x37521419 CFRunLoopRunInMode + 60
	20  GraphicsServices                    0x33e76d24 GSEventRunModal + 196
	21  UIKit                               0x3591d57c -[UIApplication _run] + 588
	22  UIKit                               0x3591a558 UIApplicationMain + 972
	23  myApp                             0x00002649 main + 96
	24  myApp                             0x000025b0 start + 52
)
terminate called after throwing an instance of 'NSException'

This error occurs most frequently when suspending an app to the background, but it can also happen randomly at other times as well. Of course, the problem here should be obvious; the crash happens entirely outside of my application code. After the call to ‘main()‘ the stack-trace that leads to the crash lies entirely within framework code. The problem appears to be that some CoreFoundation class is attempting to invoke a ‘_handleMemoryWarning:‘ selector on objects that do not support it.

So how to prevent a crash that happens completely outside of your application code? You might say “use less memory”, but that is not a reliable answer here. The ‘_performMemoryWarning‘ selector may still be invoked no matter how streamlined your memory usage is. The answer, or at least the only answer I’ve found that works reliably, is to use a custom UIApplication subclass and excise the functionality that causes this error, like so:

//
//  SafeUIApplication.h
//  myApp
//
#import <Foundation/Foundation.h>

@interface SafeUIApplication : UIApplication {
}

@end


//
//  SafeUIApplication.m
//  myApp
//
#import "SafeUIApplication.h"

@implementation SafeUIApplication

//these selectors cause crashes in random Foundation classes when the default implementation is called, so instead of crashing our app 
//we ignore these messages, hold on to the memory that has already been allocated to us, and let some other less-clever app crash instead
- (void) _performMemoryWarning {
    NSLog(@"Received a '_performMemoryWarning' call, consider using less memory...");
    return;
}
- (void) _receivedMemoryNotification {
    NSLog(@"Received a '_receivedMemoryNotification' call, consider using less memory...");
    return;
}

@end

Now before the purists and the pedants go jumping down my throat: Yes, this is a hack. Yes, it disables built-in memory-management functionality. Yes, it can mask legitimate problems if your app does in fact have a memory leak (or if it just makes inefficient use of memory). But having built-in memory-management functionality that crashes the app when called is completely unacceptable in my book, and so disabling it is fair game. Further, even with this bit of code disabled, the application will still continue to receive low memory warnings (‘didReceiveMemoryWarning‘ calls) as normal. Hanging on to memory that is already allocated to the app cannot cause the app to crash or behave incorrectly, it just means that less memory is available for other apps that are also running. That seems fair enough to me, at least so long as the default implementation of these methods causes apps to crash.

Anyways, once you’ve added the SafeUIApplication class to your project, using it is as simple as modifying your application’s ‘main.m’ file like so:

//
//  main.m
//  myApp
//
#import <UIKit/UIKit.h>

int main(int argc, char *argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, @"SafeUIApplication", @"MyAppDelegateClassName");
    [pool release];
    return retVal;
}

Just specify the SafeUIApplication classname and your UIApplicationDelegate classname, and you no longer need to worry about obscure ‘_handleMemoryWarning:‘ crashes. As noted above, be aware that this will do little to nothing to help applications that have legitimate memory usage issues. But if you are confident that your application’s memory usage is correct and you are still experiencing crashes like the one shown above then this little hack will go a very long way towards keeping your application running and stable.

Posted in coding, objective-c | Tagged , , | 1 Comment

Reunion

And now for something completely different; some light fiction:

Slowly and with much deliberation he approached, taking care to avoid her eyes and the fierce and beautiful and terrifying intensity that he knew must still burn there even after so many years. She possessed that kind of penetrating gaze which can pierce right through you and with a glance expose you to the very core, and if he was sure of anything it was that time had done nothing to bolster his ability to withstand such a thing, that it must be avoided at all costs.

But also he remembered, with more than a touch of fondness, those long-lost gossamer days where she would dare him to meet her eyes with his and wait patiently as he tried, awkwardly and unsuccessfully, to rise to the task and accept that which was being freely offered. With such a staggering clarity did he remember those days of long ago that it was as if he could reach out and touch them if he so dared. Always would he try to muster the courage and the confidence to hold her gaze, to shatter the sudden paralysis which seemed to take hold of him whenever he felt the presence of her eyes upon him, and to do whatever it was that she expected him to do (though he was never sure exactly what that might be). And always would he fail. And always would he long for his next opportunity to try and to fail.

She was close now, and had undoubtedly noticed his approach.

“Hello”, he said meekly, giving an awkward kind of half-wave as he did so.

Instantly her gaze was on him, and involuntarily he found himself bracing as if in anticipation of a mighty blow, a force of old habits long dormant but not forgotten. But this time there was no challenge, no request, no invitation framed within her bright eyes. If anything she seemed uncomfortable and awkward, mildly unsettled by his presence. And he noted this with a quiet disappointment, being careful to keep his outward demeanor unchanged. What else could he have expected, he mused inwardly, after all that had passed between then and now. What else could there be, after his failures of inaction, his failures of ineffectual action, and his failures of inappropriate action? He held her gaze, and this time found no terror there, just quiet sorrow and a dreadful still emptiness where once something vital and important had lived.

“Hi, long time no see”, she replied with an air of cordiality, stopping just short of friendliness.

And, he reflected, now at last I see what it was that so scared me all those years ago, and understand why that fear will never return to my life. In her eyes, in that beautiful and terrible gaze of hers, had lived the future. A future that could be his had he dared to just reach out and touch it. But also a future that branched out upon itself like some crazed fractal, expanding outwards through the realm of possibility and past the foreseeable horizon. A future so immeasurably vast and so full of possibility that he could not countenance the idea of grasping for it, of trying to contain it all in his feeble palm.

He had not understood that it’s not necessary or beneficial to hold the entire thing in your hand at once, that it’s entirely sufficient to grasp just a single thread and be willing to follow it to wherever it leads. The unknown had scared him then, the idea of not being able to know or to completely control what the future might hold. And he had worked hard to break himself of this childish fear, and he had done so, and in the process learned that only in the unknown can one chance upon the majestic or the sublime. Only by exploring the intricacies of the pattern firsthand does one come to understand it and gain access to those unique shared experiences that are so priceless and rare.

But that pattern from his past, that future branching out into infinite possibility that he remembered with such unshakeable clarity, was dead now. Both of them had moved on and grown up, separated at most times by thousands of miles. They had their own lives, their own places that they were accustomed to, their own independent notions of home. Never again would he or could he see the same mystifying and terrifying realm of possibilities within her eyes, or be tested with a challenge or an open invitation to come plumb its depths. All that existed there now was a simple pattern; mundane conversation, awkwardness begetting awkwardness, a few trivial branches here and there, each punctuated by a scheduled departure a few days hence. He had missed his chance, would have no more opportunity to try again, to fail again.

Too late it was when he had finally recognized himself as the explorer that he was. Too late to go back as he longed to do, and explore that myriad future the mere glance of which had so paralyzed him in his youth. That door was closed to him forever now. So he took solace in the same way that anyone who has ever touched upon something so precious and rare that it occurs once in a lifetime and then allowed it through sheer carelessness to slip through their fingers does.

“What did I know back then,” he asked himself quietly, as he slowly and somewhat dazedly wandered past the greeting area and on to the reception area where more acquaintances from years past remained.

The night passed uneventfully, and not another word passed between the two of them. A few days later, he returned home.

Posted in banter, fiction, writing | Tagged | Leave a comment

[JavaScript] setTimeout() and Closures

If you’ve done any amount of non-trivial JavaScript coding then you have probably come across the ‘setTimeout()‘ function before. In case you haven’t, this function takes a JavaScript expression and evaluates/executes it after a set delay (specified in milliseconds). For instance:

setTimeout("alert('test')", 5000);

…will display an alert box containing the text “test” after a 5-second delay. Simple enough. But what you may not know is that ‘setTimeout()‘ also supports an alternate and much more useful usage mode where instead of literal javascript text you can pass a function reference/closure and a variable number of parameters, like so:

setTimeout(alert, 5000, "test");

This will produce the same results as the first call, but the syntax is much more readable and much less prone to errors when coding. Why this variant is barely even mentioned in the documentation I cannot say, but anyone who has worked with Flash/ActionScript is probably familiar with this syntax.

There is one major limitation to this approach, however; it does not work correctly in Internet Explorer. That’s a pretty serious drawback, considering Internet Explorer’s market share. But we can fix it by overriding the default ‘setTimeout()‘ implementation as follows:

window._oldSetTimeout = window.setTimeout;
window.setTimeout = function(closureOrText, delay) {
    if (arguments.length <= 2 || typeof closureOrText != "function") {
        _oldSetTimeout(closureOrText, delay);
    }
    else {
        var funcArgs = new Array(); 
        for (var index = 2; index < arguments.length; index++) {
            funcArgs.push(arguments[index]);
        }
        _oldSetTimeout(_timeoutCallback(closureOrText, funcArgs), delay);
    }
};
window._timeoutCallback = function(closure, argArray) {
    return function() {
        closure.apply(this, argArray);
    };
};

Now the behavior will be consistent between Internet Explorer and other browsers. Note that although the default implementation only needs to be overridden in Internet Explorer, the above code will work correctly in other browsers as well. Also note that there is one more caveat to be aware of here as well. In Internet Explorer, functions provided by the system (such as ‘alert()‘, ‘escape()‘, ‘parseInt()‘, etc.) are of a different type than user-defined functions. Now this wouldn’t be a huge problem, except that whatever type Internet Explorer uses for its system functions does not support the ‘apply()‘ method (thanks, Microsoft).

So even with the above code, if you use ‘setTimeout()‘ with a system function in Internet Explorer, you will still get incorrect behavior. We can fix this by revising the code as follows:

window._oldSetTimeout = window.setTimeout;
window.setTimeout = function(closureOrText, delay) {
    var funcArgs = new Array(); 
    for (var index = 2; index < arguments.length; index++) {
        funcArgs.push(arguments[index]);
    }
    if (arguments.length <= 2 || typeof closureOrText != "function") {
        if (arguments.length <= 2 || typeof closureOrText == "string") {
            _oldSetTimeout(closureOrText, delay);
        }
        else {
            //hack for IE system functions
            _oldSetTimeout(_timeoutCallbackForSystemFunction (closureOrText, funcArgs), delay);
        }
    }
    else {
        _oldSetTimeout(_timeoutCallback(closureOrText, funcArgs), delay);
    }
};
window._timeoutCallback = function(closure, argArray) {
    return function() {
        closure.apply(this, argArray);
    };
};
window._timeoutCallbackForSystemFunction = function(closure, argArray) {
    return function() {
        if (argArray.length == 1) {
            closure(argArray[0]);
        }
        else if (argArray.length == 2) {
            closure(argArray[0], argArray[1]);
        }
        else {
            alert("WARN:  Too many arguments passed to system function; timeout callback not executed!");
        }
    };
};

This code will produce the correct behavior in Internet Explorer, and is still compatible with all other major browsers. In Internet Explorer it is limited to supporting system functions with a maximum of 2 parameters, but I’m not aware of any that require more than that anyways. An alternate workaround is to define your own function that wraps the system function, and then use the wrapper function in the ‘setTimeout()‘ call, like so:

var myAlert = function(text) {
    alert(text);
};
setTimeout(myAlert, "5000", "test");

It’s a bit less convenient to do it this way if you will be working with several different system functions, but this approach will also yield correct behavior in Internet Explorer (and is compatible with other browsers as well).

In any case, either approach can be used to get the closure-based ‘setTimeout()‘ syntax working consistently across all major browsers. And once you have that, there is very little reason to ever prefer the text-based version.

Posted in coding, javascript | Tagged , | Leave a comment

[JavaScript] parseInt() Quirks

Here’s a subtle little feature of JavaScript’s ‘parseInt()‘ function that I recently stumbled across. The radix used in the parse will default to 8 (octal) if the string you are parsing includes a leading zero. For instance:

parseInt("07");

…will return 7, as expected, but:

parseInt("08");

…will return 0, because 8 is not a valid digit in a base-8 number system. Technically the ‘parseInt()‘ function is behaving to spec in each instance, but this can lead to some very confusing errors if you’re not expecting this behavior. A simple fix exists, however:

parseInt("08", 10);

…will return 8, as expected. Explicitly specifying a radix of 10 overrides the function’s quirky default behavior (which as near as I can tell is a relic carried over from C and Java, which both use a leading zero to specify octal literals…why they didn’t opt for something more clear, like suffixing the value with ‘o’, I cannot say). Here is a quick example comparing the two.

An alternate fix to this issue is to simply override the parseInt() function, like so:

			window._oldParseInt = window.parseInt;
			window.parseInt = function(str, rad) {
				if (! rad) {
					return _oldParseInt(str, 10);
				}
				return _oldParseInt(str, rad);
			};

This will change the behavior of ‘parseInt()‘ to match that of Java’s ‘Integer.parseInt()‘ function (the radix used is always 10 unless the developer explicitly overrides it), which provides for a much more consistent and predictable experience.

Note, however, that this quirky behavior is a documented (albeit deprecated) feature of the ‘parseInt()‘ function; though it is certainly not something that one intuitively expects. Interestingly enough, its deprecation means that browser implementors are free to drop support for this confusing default at any time. However, complete removal of this feature seems unlikely to happen, as doing so would break existing websites that rely upon it.

Perhaps a reasonable middle ground would be to preserve the default behavior when the string being parsed includes only valid base-8 numbers, and default to base-10 if any other numbers are present in the string. That would help in simple cases like the ones shown above, but still may generate confusing output for inputs like “0107” and the like.

Really the problem here is one of a poorly designed spec. Instead of picking the most common usage mode and making that the default, like Java does in its ‘Integer.parseInt()‘ function, someone decided to try to infer the desired usage mode based upon the input parameter. And that may be fine when there are no ambiguous mappings from input parameters to usage modes, but that is not the case here. Whenever such ambiguous mappings exist, it is always better to just make the most common usage mode the default, and let the developer override it if they want something different.

Otherwise you produce code that can yield confusing and unexpected behavior, and you dig everyone else into a hole where they must continue both supporting and working around your poor design decision.

Posted in coding, javascript | Tagged , | 3 Comments