JonHoyle.com Mirror of MacCompanion
http://www.maccompanion.com/macc/archives/October2007/Columns/AccordingtoHoyle.htm

Resources

 

Consultants

Developers

Devotees

Downloads

"Foreign" Macs

Forums

Hearsay

Link Lists

Mac 3D

Macazines

Mac Jobs

MUG Shots

News

Radio

Reviews

Think Different

Training


Google

macCompanion

Internet





Evo Networks



Latest Joy of Tech!
Latest Joy of Tech!


3-Rivers Synergy Centre


Visit StepHouse Networks. Broadband DSL for Apple Users







 

According to Hoyle...

Looking Forward to Mac OS X 10.5 Leopard, Part III: Objective-C 2.0 Enhancements


[ Part I | Part II | Part III ]

by Jonathan Hoyle

jonhoyle@mac.com

macCompanion

October 2007

http://www.jonhoyle.com

 


This month, Apple will be introducing the sixth major release of Mac OS X: version 10.5 Leopard. With each release, Mac OS X has succeeded in improving stability, usability and power. Earlier this year, Microsoft released Vista, an update to it Windows operating system, with somewhat disappointing sales. To get an interesting (and very amusing) comparison of Vista and the current Mac OS X 10.4 Tiger, I strongly suggest you visit this YouTube video (taken from last year's Worldwide Developer's Conference).

 

As the video suggests, Vista is an attempt to copy Mac OS X's past. This month's release of 10.5 Leopard is a big step toward the Mac's future.

 

In July, we began our look with an overview of the 2007 Worldwide Developer's Conference. In August, we examined in earnest the changes coming in Leopard from a user's perspective, and then last month, we reviewed Xcode 3, Apple's new development tool update for Leopard. You can view these articles here:

This month, we begin concentrating on specific issues related to Leopard software development. As mentioned in previous columns, Mac OS X 10.5 Leopard is still prerelease software and is under a Non-Disclosure Agreement. For that reason, I can relay only on information that Apple has already revealed to the public, despite Leopard's release being only a couple of weeks away.


Between now and Mac OS X 10.5's release, an excellent resource is at: Apple's Leopard page.

 


The 64-bit Challenge


The price of 64-bit development went up by a lot this year, with Apple announcing that Carbon development is unsupported beyond 32-bit. Carbon is the C/C++-based programmer's interface which traces its history back to the original Macintosh from 1984. Until very recently, the vast majority of commercial Macintosh products were built with Carbon. The announcement to desupport 64-bit Carbon came as quite a surprise for many, as Apple's remarks at last year's WWDC was completely the reverse. In 2006, Apple provided a 64-bit Transition Guide for Carbon, detailing a process for developers to port their Carbon projects for 64-bit compilation. Many companies spent this past year affecting those changes, just to discover in June that the rug has been pulled out from under them. Carbon projects slated for 64-bit support have to be completely rewritten to have any chance of becoming 64-bit.

 

To take advantage of the 64-bit operating system, most developers will be switching to the Objective-C based Cocoa API. However, there are other possibilities. Darwin, Unix and X11 developers will see no impediment moving to 64-bit with their current code base. Likewise, Java developers will be able to run virtually unmodified in 64-bit mode on Intel-based Macintoshes (although PowerPC-based Macs will run Java in 32-bit only, even on the 64-bit G5 processor). Those developing in frameworks may find themselves in trouble, since most Mac-supported C++ frameworks are Carbon-based. Trolltech's Qt framework uses Carbon and thus Qt-based apps will not be 64-bit any time soon. Trolltech announced their decision to change their Mac OS X implementation from Carbon to Cocoa, but they have no idea how long this is going to take. Those using the open source wxWidgets framework are in a slightly better position. Although the main Mac OS X branch of wxWidgets is Carbon-based, there has been a ongoing initiative for the last several years for a Cocoa implementation, called wxCocoa. It seems to me that suddenly wxCocoa will begin to receive attention from a much wider audience. I have seen no official word from other C++ frameworks like CPLAT or FLTK, but it cannot be good news for them. Even non-C++ project may be impacted, such as those using the very popular REALbasic development environment, which is still primarily written in Carbon.

 

For more information on transitioning to 64-bit development, visit Apple's 64-bit page on Leopard.

 


Objective-C & Leopard


With Apple's elimination of Carbon from 64-bit discussion, the Objective-C programming language is no longer an option for the Macintosh software developer. The reason for this is that the Cocoa API's native language is Objective-C, and to use Cocoa, you must acquire fluency in this language. Many longtime C/C++ programmers have resisted having to learn it, since all their needs were satisfied by Carbon in C and C++. Unfortunately, those days are coming to an end, and Mac developers who wish to remain relevant will want to learn Objective-C.

 

"Isn't Java also a supported language for developing Cocoa applications?" someone is bound to ask. Well no, not any more unfortunately. In the early days of Cocoa on Mac OS X, Apple recognized that there was a great deal of resistance in using a relatively obscure programming language like Objective-C. So to be as receptive as possible, Apple provided two language accesses for the Cocoa API: Objective-C and Java. The choice of adding Java was an obvious one, due to its immense popularity amongst developers. Apple's hope was that Cocoa would become embraced by the huge hordes of Java developers. This turned out not to be the case, as Java programmers continued to prefer cross-platform APIs, such as AWT and Swing. C/C++ programmers remained with Carbon, leaving only academics and old NeXT developers (already familiar with Objective-C) interested in Cocoa. So Apple has recently announced that the use of Java for Cocoa development is officially deprecated with Leopard. Objective-C is the only Apple-supported language for Cocoa development moving forward.

 

Despite its deprecation, there remains a small but strong contingent of Cocoa/Java developers who plan to stay with their technology for as long as it remains viable. If you wish to learn more about developing Cocoa applications with Java, check out this MacTech article: Writing Cocoa Applications in Java.

 


Objective-C History


Objective-C is not a new language by any means. It was created in the early 1980's during a time when Object Oriented programming was just starting to become mature. Although there were already a number of pure O.O. languages in existence, these were mostly niche languages with a small number of advocates. The development community yearned for a way to extend the popular C programming language in such a way as to become object oriented. There were many object-oriented variants of C which were developed, including THINK C with Objects used by many Macintosh developers. These language variants for the most part died away as C++ became standardized. So powerful and so influential did C++ become, that the vast majority of newer languages today have adopted the C++ syntax style of object-dot-method-left parenthesis-ordered argument list-right parenthesis. Those learning Java, PHP, Ruby or others will find it very easy to go from one language to another because of this widespread syntax adoption.

 

Objective-C was an early variant that did not adopt this standard syntax. Instead it used the rather unusual Smalltalk bracket syntax, with an argument list prefixed by tags and colons. It lacked most of the rich features found in C++ but did have some powerful capabilities not available in C++, namely Reflection and a dynamic runtime model. Despite these advantages, it remained a niche language, surviving almost exclusively on NeXT computers. When Apple bought NeXT in December 1996, Objective-C became available for Macintosh developers.

 

With Mac OS X 10.5 Leopard, Objective-C is seeing its first major facelift, adding a number of new features to the language to make it on par with other modern languages. This update is called Objective-C 2.0, and we will be looking at some of it new features this month.

 


Automatic Garbage Collection


The most significant of enhancement coming to Objective-C 2.0 is Garbage Collection: the language runtime process which automatically deletes allocated memory which is no longer in use. Essentially all modern languages (post-C++) do this, and adding this capability to Objective-C 2.0 shows Apple's commitment to its preferred language.

 

Garbage Collecting in Objective-C 2.0 is an Opt-In proposition, so you choose to turn it on if you wish:

 


 

Although you may have some older Objective-C projects that you do not wish to take the time to convert, all new projects should start with this flag turned on by default. It is fully supported in Cocoa and all public frameworks, as all NSObjects are collectable. It does not, however, rewire or replace C's malloc() function or C++'s new operator, so you must replace these yourself.

 

If you are converting an old project, you need to be concerned about older memory management calls, as -retain, -release, -retainCount, -autorelease and -dealloc are each ignored when GC is turned on. However, the equivalent CoreFoundation functions CFRetain() and CFRelease() remain meaningful, as they are meant to be available to Carbon/C++ developers as well.

 


Fast Enumeration (foreach)

 

Another feature added to Objective-C 2.0 is what Apple calls Fast Enumeration. It is essentially what modern languages call a ForEach capability. The best way to explain it is to see the code for yourself. In this example, we have an Objective-C method which takes an NSArray of MyObjectType, and iterates through the array looking for the first one which returns true from a call to -isSpecial. In Objective-C 1.0, such code might look something like this:

 

   -(MyObjectType *) getSpecialObject:(NSArray *) myArray
   {
      NSEnumerator *myEnumerator = [myArray objectEnumerator];
      MyObjectType *myObject;

      while (true)
      {
         myObject = [myEnumerator nextObject];
         if (myObject == nil)
            break;
         if ([myObject isSpecial])
            return myObject;
      }

      HandleErrorCondition();
      return nil;
   }

 

First, an NSEnumerator has to be created for our loop. With each iteration, a call to -nextObject has to be performed to acquire the next item, a check against nil is made so as to see if the array is completely traversed, and then finally a call to -isSpecial is made to see if we have found our object. This was a slow and memory intensive procedure, primarily because we rely on the NSEnumerator to tell give us the object (or nil when it is completed). With Objective-C 2.0, this same code could be written more simply as:

 

   -(MyObjectType *) getSpecialObject:(NSArray *) myArray
   {
      for (MyObjectType *myObject in myArray)
         if ([myObject isSpecial])
            return myObject;

      HandleErrorCondition();
      return nil;
   }

 

Here, all of the enumeration complexity of the prior code sample is completely subsumed by the for( in ) syntax. In some other languages, this same syntax is used except the for keyword is replaced by the foreach keyword. With this, no NSEnumerator is needed, and the code is more concise and readable.

 


Finally! The Dot Operator!

 

One of Objective-C's biggest annoyances is its ugly syntax. In almost all other C-based languages, square brackets are used exclusively for array indexing. Finding objects, methods and colons sprinkled inside standalone brackets strikes the new programmer as dismayingly bizarre. For example, the same function written in C++ and Objective-C may be invoked this way:

 

   myReturnVal = myObject.foo(parm1, parm2, parm3); // C++
   myReturnVal = [myObject foo:parm1, bar2:parm2, bar3:parm3]; // Objective-C

 

I wish I could tell you that with Objective-C 2.0 the brackets are gone. Unfortunately, I cannot. However, I can tell you that many of the instances in which they were required can now be avoided with the use of the standardized Dot Operator. One can now obtain property data from an Objective-C class this way. For example, the following two lines are now equivalent:

 

   z = [x y];   // Objective-C 1.0 syntax
   z = x.y;     // Objective-C 2.0 syntax

 

Likewise, the setting of property data can also be done this way:

 

   [x setY:z];  // Objective-C 1.0 syntax
   x.y = z;     // Objective-C 2.0 syntax

 

This works with any -name / -setName:accessor pattern. Essentially, anything that looks like an accessor method can now be dotted. The only limitation is that x must be a known class type. Unfortunately, the declaration of these properties still remains munged in Objective-C's peculiar syntax:

 

   @interface MyClass
   @property(attributes) type name;
   // equivalent to:
   - (type) name;
   - (void) setName:(type)name;
   @end

 


Objective-C Adopting the C++ Exception Model

 

Like C++, the Objective-C has an exception model built into the language. Unfortunately, its implementation is a very poor one relative to C++. In C++, an exception check is designed to be essentially zero cost. The cost of entering a try block is not more than entering any new scope. The performance hit is taken only during a throw, that is, when the exceptional circumstance actually takes place. This is important since the performance cost of a throw is an order of magnitude greater than a try.

 

In Objective-C 1.0, the reverse is the case: the @try call takes an order of magnitude longer than the actual @throw Since a typical programmer will enter a try block far more often than throw from it, exception handling becomes an expensive proposition for the Objective-C developer. Apple has addressed this matter in Objective-C 2.0. Although backward compatibility prevents Apple from changing this model for 32-bit applications, 64-bit applications written with Objective-C 2.0 will use the zero cost C++ exception model. With this, entering a try block becomes fast and throw-ing an exception would be slow.

 

Another nice feature is the interoperability of exceptions between Objective-C 2.0 and C++. The C++ catch(...) will catch Objective-C exceptions, whilst throw rethrows them. Likewise, Objective-C has implemented a new @catch(...) call, which will catch any uncaught exceptions (including C++ exceptions) and @throw rethrows them.

 

Despite the different models used between the 32- and 64-bit runtimes, exception handling remains mostly source compatible. The main difference being that in 32-bit, the new @catch(...) call is implemented like @catch(id e).

 


For more on Objective C 2.0, check out this tutorial.

 


Coming Up: More development advice for Mac OS X 10.5 Leopard and beyond. See you in 30!

 

[ Part I | Part II | Part III ]



http://www.maccompanion.com/macc/archives/October2007/Columns/AccordingtoHoyle.htm