Jump to content

Objective-C

From Wikipedia, the free encyclopedia

This is an old revision of this page, as edited by Maury Markowitz (talk | contribs) at 12:48, 26 June 2002. The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

Objective-C (or Obj-C) is an object oriented programming language implemented as an extension to C. It is used primarily on Mac OS X and GNUStep, and was the previously primary language used in NeXTSTEP and OpenStep.

History

In the 1980's common software engineering practice was based on structured programming, and was having serious problems "scaling up" to deal with the larger and more complex problems that were now being addressed on computers. Many saw object oriented programming as a potential solution to the problems. In fact Smalltalk had already addressed many of these issues, and OO in general became very much in vogue for a time.

However the field was still quite unsophisticated. People would oversell the advantages of OO programming, and attempt projects that were simply not possible. Worse, many of the tools were immature or had unrealistic requirements (like Smalltalk, which takes over the entire computer). It wasn't long before a backlash started, with the general concensus being that there was no way out of the software engineering problem, because software was fundamentally different than tangible goods, like cars.

Obj-C was created primarily by Brad Cox in the early 1980s. He had become interested in the problems of true reusability in software design and programming. In order to demonstrate that real progress could be made, Cox set about to show that making interchangeable software components really needed only a few practical changes to existing tools. Specifically they needed to support objects in a flexible manner, come supplied with a set of libraries that was actually usable, and allow for the code and any resources needed by the code to be bundled into a single cross-platform format.

The main description of Objective-C in its original form was published in his book, Object-oriented Programming, An Evolutionary Approach in 1986. Cox was careful to point out that there is more to the problem than the language, ut it appears this fell on deaf ears. Instead the system found itself compared on a feature-for-feature basis with other languages, missing the forest for the trees.

Language basics

Objective-C's syntax is based on Smalltalk, and is is different from that of C or C++. The code:

int doSomething (int i) {
   return squareRoot (i);
}

from the C world would become:

- (int) doSomething: int i
{
   return [self squareRoot: i];
}

This may look like a bad idea all around, but it did have one redeeming value; named parameters:

- (int)changeColorWithRed:int r Green: int g Blue: int b

which would be invoked thus:

[myColor changeColorWithRed:5 Green:5 Blue:5];

Objective C is a dymamically typed language, as is Smalltalk. As with other dynamically typed languages, there is the potential problem of an endless stream of run-time errors that come from sending the wrong message to the wrong object. However Objective C allows the programmer to optionally identify the class of an object, and in those cases the compiler will apply strong-typing methodology. In fact most programs use this extensively in order to avoid these problems.

However when one does need dynamic typing, it becomes tremendously powerful. In order to facilitate flexible programming, all Objective C objects include a "second chance" method that will be called with the original method invocation passed into it as a parameter. Typically this simply reports an "unknown method" error, but the same system can be used to serialize the method call and send it over the network for instance.

Consider a simple example, placing an object in a container. In a strongly-typed language like C++, the programmer is forced to write a template, i.e. a class parameterized by type. Template programming can be cumbersome and tricky, and quickly leads to code bloat. Alternatively, more weakly-typed languages like Java allow collections of anonymous Objects, but these must be cast back and forth between the anonymous type and the real type. This is annoying when you consider that it was a string when you put it in there three lines earlier, and now you have to tell the compiler that it's a string coming back out just to call toUpperCase().

Categories

Cox's main concern was the maintainability of large code bases. Experience from the structured programming world had shown that one of the main ways to improve code was to break it down into smaller pieces. Objective C added the concept of Categories to help with this proccess.

A category collected method implementations into separate files. That way the programmed could place large methods in its own "category" to make it more readable. For instance, one could create a "SpellChecking" category "on" the String object, collecting all of the methods related to spell checking into a single place.

That might not sound like anything new, but one key aspect of the implementation is that the methods were added to the class at runtime. That means that the programmer can add categories to existing classes without them knowing about it. If the system you are supplied with does not contain a spell checker in its String implementation, you just add it.

Combining categories with dynamic typing produces a synergy that results in tremendous flexibility that is largely unexpected in most programming systems. Consider Java: simply allowing String to have a checkSpelling method added isn't enough on it's own, because the rest of your program won't allow you to call that new method - all methods must be known at compile time. Instead you must use helper objects, special proxy classes, or use the terrible visitor pattern, all of which add to the complexity and uglyness of the implementation.

But the usefulness of categories goes further. Since any method can be "covered" by one in a category at runtime, you can in fact fix bugs in existing compiled binaries. Once you get used to having this, you can't live without it. It is so powerful that subclassing in general is much more rare in Objective C programs, typically limited entirely to your private data objects.

A number of other languages have attempted to add this feature in a variety of ways. TOM took the Objective C system to its logical conclusion and allowed for the addition of variables as well. Other languages have instead used prototype oriented solutions, the most notable being Sel).

Other features

Obj-C in fact included a laundry-list of features that are still being added to other languages, or simply don't exist at all. These led from Cox's (and later, NeXT's) realization that there is considerably more to programming than the language. The system has to be usable and flexible as a whole in order to work in a real-world setting.

  • all libraries are dynamically linked. This meant that large Objective C programs were in fact quite small, because the library was already on the machine. Common today perhaps, but this is from the early 1980s, remember.
  • libraries can be supplied in multiple versions in a single file, and applications can choose to use a specific version (4.3.2), the latest version (which happens to be 5.2.1), or even the latest of a pariticular major relase (anything from 4.x). Versioning problems like this continue to haunt systems to this day, including Java and COM
  • code can be provided in multiple object formats for different platforms, which avoids the need for a virtual machine entirely. Typical multi-platform Objective C programs are smaller than most single-platform programs on other systems.
  • delegation is trivial. Simply add a category that changes the "second chance" method to forward the invocation to the delegate. Presto.
  • remote invocation is trivial. Simply add a category that changes the "second chance" method to serialize the invocation and forward it off.
  • swizzling allows for classes to change at runtime. Typically used for debugging (freed objects are swizzled into Zombies, who's only purpose is to report an error when someone calls them). swizzling was also used in EOF to create database faults

Advantages

Obj-C is a very "practical" language. It uses a thin runtime written in C, whereas most OO systems of the era used large VM runtimes that took over the entire system. Programs written in Obj-C tended to be not much larger than the size of their code and that of the libraries (which often didn't have to be included in the distribution), in contrast to Smalltalk systems where you needed huge amounts of memory just to open a window.

Likewise the language was implemented on top of existing C compilers (first as a pre-processor, later as a gcc module) rather than as a new compiler. This allowed Obj-C to leverage the huge existing collection of C code, libraries, tools, and mindshare. You can easily wrap existing C libraries - even in object code libraries - in Obj-C wrappers to give them an OO style and more easily use them in OO programs.

All of these lowered the barrier to entry, likely the biggest problem for the widespread acceptance of Smalltalk in the 1980s. (Note that "huge amounts" above is in terms of early 1980s, when a certain person claimed 640K to be enough for anybody).

In general Objective C can be summed up as offering all the flexibility of the later Smalltalk systems, in a language that is deployed as easily as C.

Disadvantages

The first versions of Objective C did not support garbage collection. At the time this was a matter of some debate and many people considered the long "dead times" when Smalltalk did collection to render the entire system unusable. Obj-C avoided that problem by not including this feature. However in retrospect this is a serious oversite. Although some 3rd party implementations have added this feature (most notably GNUStep), it remains outside the standard.

Another problem is that Obj-C does not include a namespace mechanism. Instead programmers are forced to add prefixes to their class names, a poor solution at best. Adding a namespace system would be simple and natural under Obj-C (where they map onto the libraries system quite cleanly) so it is somewhat surprising this hasn't happened.

Finally, since the language was based on C compilers, it remains highly dependant on a header file to work well. This is an added complexity that is no longer nessesary and thankfully missing from most modern languages like Java or C#.

See also: