Tuesday, October 20, 2009

XCode 3.x

I've been coming up to speed on iPhone development and thought I'd share some of my experiences.

The first is that Beginning iPhone 3 Development is a very useful starting point. I tried a couple of other resources but finally settled on this. I do like books better than video when learning a new environment but this book also has the advantage of being up-to-date and accurate. I hate trying to learn an environment/languiage when the examples are wrong! Beginning iPhone 3 Development employed a technical reviewer who worked and verified all of the examples. Shouldn't every book like this have a technical reviewer? -- the world would be a better place.

A few observations on the development environment, which although reasonable is a bit more primitive than netbeans or eclipse, especially around refactoring
renaming a class/header file doesn't rename all of the imports throughout the project, and there isn't a "Refactoring" capability that I've found that does this.

The C aspects certainly harken back to an earlier era, e.g., one has to define a function in a .m file and declare it in a .h file for it to work correctly. At least Code Sense minimizes the chances for mistyping in this case.

XCode only allows you to view the interface specification (the .xib file) via the interface builder--however it is useful to realize that the .xib file is really an xml file that can be viewed in a normal text editor e.g., emacs.

Misspellings count and don't seem to generate errors:
  • Surprised that Code Sense doesn't prompt when overriding methods from the superclasses, which causes the the classic "why wasn't this method called debugging session"

  • Similarly the compiler doesn't tell if you're calling undefined methods

  • Misspelling accessor e.g.,
    childController.tltle = prez.name;
    childController.title = prez.name;
    gets the error: request for member ‘tltle’ in something not a structure or a union

Also can't believe that there isn’t enough introspection so that you still have to do these:

#pragma mark NSCoding
-(void)encodeWithCoder:(NSCoder *)encoder{
[encoder encodeObject:field1 forKey:kField1Key];
[encoder encodeObject:field2 forKey:kField2Key];
[encoder encodeObject:field3 forKey:kField3Key];
[encoder encodeObject:field4 forKey:kField4Key];
-(id)initWithCoder:(NSCoder *)decoder{
if(self = [super init]){
self.field1 = [decoder decodeObjectForKey:kField1Key];
self.field2 = [decoder decodeObjectForKey:kField2Key];
self.field3 = [decoder decodeObjectForKey:kField3Key];
self.field4 = [decoder decodeObjectForKey:kField4Key];
return self;
#pragma mark -
#pragma mark NSCopying
-(id)copyWithZone:(NSZone *)zone{
FourLines *copy = [[[self class] allocWithZone:zone] init];
copy.field1 = [[self.field1 copyWithZone:zone] autorelease];
copy.field2 = [[self.field2 copyWithZone:zone] autorelease];
copy.field3 = [[self.field3 copyWithZone:zone] autorelease];
copy.field4 = [[self.field4 copyWithZone:zone] autorelease];

On The Bright Side

@synthesize obviates a lot of useless typing.

Categories seem cool and I plan to explore them further. Categories let you add methods to an existing class -- the source code of the existing class is not required.

From the xcode 3.1 doc Categories

  • Provide a simple way of grouping related methods. Similar methods defined in different classes can be kept together in the same source file.

  • Simplify the management of a large class when several developers contribute to the class definition.
    Let you achieve some of the benefits of incremental compilation for a very large class.

  • Can help improve locality of reference for commonly used methods.
    Enable you to configure a class differently for separate applications, without having to maintain different versions of the same source code.
    To declare informal protocols.
    See “Informal Protocols ,” as discussed under “Declaring Interfaces for Others to Implement.”

The doc also contains a suitable caveat:
Although the language currently allows you to use a category to override methods the class inherits, or even methods declared in the class interface, you are strongly discouraged from using this functionality. A category is not a substitute for a subclass.

That is, categories are powerful and can blow your foot off, the "power tool" version of shooting yourself in the foot, if you're not careful.

You can schedule actions to happen in the future and then cancel them when superseded by a subsequent user action.
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(singleTap) object:nil];
[self performSelector:@selector(doubleTap) withObject:nil afterDelay:.4];

It is very nice to have that capability just "built in."