A Bit More Objective-C from a Java Point of View

by James Duncan Davidson


Now that I have recovered from JavaOne, I have been once again exploring the terrain of Cocoa. And in the process, I've been digging deep again into Objective-C. In a previous weblog I discussed a few of the differences between Objective-C and Java. Now I'm going to take a look at a couple of things that are annoying, and sometimes painful, about working in Objective-C. Especially when coming from a Java background.



First up, Objective-C is based on the strict ANSI C standard. This means that you are limited to declaring new variables to the top of a block of code. What happens in practice is that the following code (a snippet that all Java programmers have used a bazillion times and have automatically programmed into their fingertips) will not compile:




for (int i = 1; i < j; i++) {

    // do stuff

}




Instead, you need to write your code to look something like:




int index;

for (index = 1; index < j; index++) {

    // do stuff

}



This looks innocent enough in the example above, but most methods have a page or two (hopefully not more!) of implementation. In real life, the example looks more like the following:




int index;

// Lots of code in method...

[[NSColor whiteColor] set];

NSRectFill(rect);

for (index = 1; index < j; index++) {

    // do stuff

}



Declaring an index a page before the for loop that uses it is quite annoying. Or declaring any short-lived variable too far from where it is being used is a sure way to run into readability problems. At WWDC it was mentioned that this problem will likely go away as the C support is upgraded. Until that happy day, there is a work-around. Simply open a new block of code with curly-braces. Here's an example:




// previous code in method...

[[NSColor whiteColor] set];

NSRectFill(rect);

{

    int index;

    for (index = 1; index < j; index++) {

        // do stuff

    }

}




The second issue is one that is not picked up the by the compiler. It is the accidental case of using an `=` assignment operator in an if(condition){} statement instead of the `==` comparison operator. There have been at least three cases in the last few days where the following code caused non-obvious problems in my programs:




if (answer = NSAlertDefaultReturn) {

    sp = [NSSavePanel savePanel];

    [sp setRequiredFileType:@"expenses"];

    answer = [sp runModal];

    // ...

}



The above code will compile just fine, but trying to figure out what is happening at runtime can get a little tricky. Even if you have a hint of the problem, having to scan pages of code looking for a single missing '=' character can make your eyes cross.



Are these issues enough to keep me from further experimentation with Objective-C? Nope. Not at all. But they do constantly annoy me as I explore the language and the Cocoa frameworks. They take a little bit of the shine off of an otherwise enjoyable experience. Just enough to make me really appreciate some of the polish that the creators of Java put into the language and its semantics.



Are you a Java programmer taking a few baby steps into Objective-C? If so, what have been your experiences?


3 Comments

rblancha@rbi.com
2001-06-21 14:17:03
-Wall
Thanks for the interesting article. In regards to Objective-C not providing the assignment warning, it looks like you can get the compiler to generate these by passing -Wall instead of -Wmost as an option to the compiler. I tried a single test case and it seemed to work though you still need to dig the warning out of the text spewed as part of the build. I found this suggestion on one of our web sites:
http://www.allosx.com/993104984/index_html


Thanks again,


Rich

duncan
2001-06-21 16:28:17
-Wall
Thanks for your comments.


Regarding your tip, wow! Thanks! That worked wonders. In Project Builder I dug in and changed the "Build Settings" flag "WARNING_CFLAGS" (under Targets, Build Settings) to -Wall instead of -Wmost, and sure enough the warning of the assignment was displayed.


Very cool.

donarb
2001-06-22 09:10:34
-Wall
Another way of catching assignment errors is to code the constant on the left side of the equals sign. The compiler will catch it if you do this:


if (0 = returncode) ...


Don