Wednesday, November 17, 2010

Investigating initialization errors

I spent some time this evening investigating two errors thrown by XCode that baffled me for a bit today.

I wrote some methods like this:

#import "MyClass.h"

@implementation MyClass

- (void)refreshImageView:(UIImageView *)imageView {
   
    CGFloat newHeight = [self modifyHeightFromFrame:imageView.frame];
   
    // ...
}

- (CGFloat)modifyHeightFromFrame:(CGRect)frame {
    float modifier = .10;
    return frame.size.height * modifier;
}

@end

My build failed with the following error: "Incompatible types in initialization" appearing at the line in which I was calling the method. Obviously when assigning a CGFloat to a CGFloat everything looks OK, so why the error?

The problem was I had not yet put the method signature into the header file. I found that because the method returning the CGFloat value was located below the method call, the compiler didn't know about the method or what its return type was. Including a method signature like the one below solved the problem.

/* MyClass.h */

@interface MyClass : NSObject {
    // ...
}

// Method signatures
- (CGFloat)modifyHeightFromFrame:(CGRect)frame;

@end

I wanted to further investigate the reason why you receive this error instead of a nice warning message, because typically in cases like this you will receive a warning like this one

'Class' may not respond to '-method'Name'

However, this case is slightly different (I'll explain why shortly) because the error thrown trumps any warnings and we therefore do not receive that helpful warning. The warning is helpful in two ways: 1) it clues me in to the fact that I have forgotten to add my method signature to the class header file or have forgotten to include the header file altogether and 2) the warning is typically accompanied by a helpful explanation. When viewing the Build Results a little note appears below the warning. If you click 'more' you could see the message explains

Messages without a matching method signature will be assumed to return 'id' and accept '...' as arguments.

What this tells us is that because XCode doesn't recognize the method (due to the missing signature/method declaration), it will assume the return type of the method to be an id (the value of which is a memory address pointing to an object of type void*).

OK fine, so why all the fuss? Well if we take a deeper look into CGFloat we discover that it is really just a typedef for float or double depending on your architecture. And then we find that float/double values (non-integer, primitive data types) can not receive a cast of a pointer value (memory address). Here lies the explanation behind the previously mysterious error. The compiler was trying to initialize a float value with a memory address, and complained with an initially ambiguous error.

Now, however, we are more informed what this error message could mean in the future and will know possibly where to look when we don't receive our nice little warning message.

I might also note that when trying to initialize a structure such as CGRect or CGSize with an undeclared method, you will receive an equivalent error message:

Invalid initializer

Which essentially means "Hey! I can't initialize a structure with only a memory address." And if you try to cast the result instead, you'll receive an error message:

Conversion to non-scalar type requested

All that being said, it all boils down to this: Don't forget to declare your method signatures and include your header files!

Friday, October 29, 2010

Discovering online developer resources

One reason for which I had the desire to start a blog was to create a storage point for all the useful information that I encounter on a day-to-day basis as a software developer. Many times I'll spend an hour researching a problem or a topic and thought it would be great to store my list of aggregated sources and findings in a spot publicly accessible by others.

So today I'll share two quick links I found just a minute ago:
  • Dr Dobbs - Online software journal articles and blogs. A resource I am hoping will help shed light on the latest encouraged practices within the sphere of development.
  • FreeTechBooks - Probably quite the opposite of staying current, but free access to hundreds of tech books (most of which at initial perusal seem a bit dated).