The other day a work colleague of mine ran into some troubles with an unrecognized selector exception crashing his iPhone application…the exception looked something like this:
NSInvalidArgumentException’, reason: ‘-[__NSArrayI addObject:]: unrecognized selector sent to instance …..’
After much frustration, and a fair bit of time spent with a bunch of us trying to hunt down the problem, it turned out to be a problem that could have been noticed immediately had the compiler been strongly (stronger) typed. Yes, ultimately the problem arose due to programmer error, however, this particular instance is just one example of why I prefer strongly typed languages (such as Java).
The error came about as a result of attempting to add an object to an NSMutableArray type that was actually pointing to an NSArray object. This type of scenario is shown in some demo code below:
NSString *test = @"test";
NSMutableArray *mutableArray = [[NSMutableArray alloc] init];
[mutableArray addObject:test];
NSArray *immutableArray = [[NSArray alloc] init];
mutableArray = immutableArray;
[mutableArray addObject:test]; // Exception: unrecognized selector
From the above code, it is easy to see that a subclass type is being assigned to a superclass type. In Java, for instance, this would immediately have been flagged as an error (conversion error between types), and the problem resolved fairly quickly. To be fair to Objective-C, a warning is given when attempting to perform an incompatible assignment, however, this simply just does not seem to be enough sometimes and the result can be a real pain for developers. Fortunately, this time around, it was not myself who bore most of this pain đ