Objective-C

Objective-C, often referred to as ObjC or more seldom as 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, two environments based on the OpenStep standard, and is the primary language used for the NeXTSTEP, OPENSTEP, and Cocoa application frameworks. Generic object-oriented Objective-C programs that do not make use of these libraries can also be compiled for any system supported by gcc, which includes an Objective-C compiler.

Contents

History

In the 1980s common software engineering practice was based on structured programming. Structured programming was implemented in order to help "break down" programs into smaller parts, primarily to make them easier to work on as they grew increasingly large. However, the power of the computers and the tasks they were being used for quickly overwhelmed the abilities of structured programming to solve them.

Many saw object-oriented programming as a potential solution to the problem. In fact Smalltalk had already addressed many of these engineering issues, and some of the most complex systems in the world were Smalltalk environments. On the downside Smalltalk used a virtual machine to run in, one that was very large and tended to require huge (for the time) amounts of memory, or run very slowly.

OO in general became very much in vogue for a time, perhaps before it was ready. People would oversell the advantages of OO, and attempt projects that were simply not reasonable. Worse, many of the tools were immature or had unrealistic requirements. It wasn't long before a backlash started and people rejected OO as yet another problem.

In the end the engineering community as a whole seemed to adopt a curious attitude. The common consensus was there was no way out of the software engineering problem, because software was fundamentally different from tangible goods, like cars.

ObjC was created primarily by Brad Cox in the early 1980s at his company Stepstone. 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 were 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, but 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 is a very "thin" layer on top of C. Objective-C is a strict superset of C. That is, it is possible to compile any C program with an Objective-C compiler, which cannot be said of C++. Objective-C borrows its syntax from both C and Smalltalk. Most of the syntax, including the traditional function calls, is borrowed from C, while the syntax for certain object-oriented features, including message-passing, is borrowed from Smalltalk.

Messages

The syntax change is for sending messages to objects, and is based on the programming model of Smalltalk, in contrast to the programming model of Simula used by C++. It is an important semantic distinction, that in Objective-C one does not call a method, one sends a message.

An object called obj which has a method doSomething implemented is said to respond to doSomething. If we wish to send a doSomething message to obj, we write

[obj doSomething];

What is markedly different from such statically typed languages such as C++ and Java in that the programmer can send messages to objects that do not respond to them. See the dynamic typing section below.

Interfaces and implementations

Objective-C requires the interface and implementation of a class to be in separate specially declared code blocks. By convention, the interface is put in a header file and the implementation in a code file.

Interface

The interface of the class is usually defined in a header file. Convention is usually to create the name of the header file based on the name of the class. So if we have the class Thing, Thing's interface goes in the file Thing.h.

The interface declaration is in the form

@interface classname : class to inherit from
{
   instance variables
}
+ class method
+ class method
 ...
- instance method
- instance method
 ...
@end

Implementation

The interface only declares the prototypes for the methods, and not the methods themselves, which go in the implementation. The implementation is usually stored in, for example, Thing.m. The implementation is written

@implementation classname
+ class method
{
   implementation
}

- instance method
{
   implementation
}
 ...
@end

Methods are written in a different way than in C. For example, in C, we write

int do_something(int i)
{
   return square_root(i);
}

with int do_something(int) as the prototype.

In Objective-C however, this becomes, in the implementation

- (int) do_something: (int) i
{
   return [self square_root: i];
}

The hyphen lets us know that this is an instance method, and not a class method (which uses a +). This syntax may appear to be more troublesome but it allows the naming of parameters, for example

- (int) changeColorWithRed: (int) r  green: (int) g  blue: (int) b
...

which would be invoked thus:

[myColor changeColorWithRed:5 green:5 blue:5];

If myColor was of the class Color, internally, instance method changeColorWithRed would be _i_Color_changeColorWithRed_green_blue. The i is to refer to an instance method, then the class and then method names with colons translated to underscores.

Protocols

Objective-C was extended at NeXT to introduce the concept of multiple inheritance of specification, but not implementation, through the introduction of protocols. This is a pattern achievable as an abstract multiply inherited base class in C++ or, more popularly adopted in Java as an "interface". Objective-C makes use of both ad-hoc protocols, called informal protocols, and compiler enforced protocols called formal protocols.

An informal protocol is a list of methods that a class can implement. It is specified in the documentation, since it has no presence in the language. Informal protocols often include optional methods, where implementing the method can change the behavior of a class. For example, a text field class might have a delegate that should implement an informal protocol with an optional autocomplete method. The text field discovers whether the delegate implements that method (via reflection), and if so, calls it to support autocomplete.

A formal protocol is similar to an interface in Java. It is a list of methods that any class can declare itself to implement. The compiler will emit an error if the class does not implement every method of its declared protocols.

The syntax

@protocol Locking
- (void)lock;
- (void)unlock;
@end

denotes that there is the abstract idea of locking that is useful and when stated in a class definition

@interface SomeClass : SomeSuperClass <Locking>
...
@end

that instances of SomeClass will provide an implementation for the two instance methods using whatever means they want. This abstract specification is particularly useful to describe, for example, the desired behaviors of plug-ins for example, without constraining at all what the implementation hierarchy should be.

Dynamic typing

Objective-C is a dynamically typed language, as is Smalltalk. This means that we can send to an object a message that is not specified in its interface. This may seem like a bad idea, but in fact this allows for a great level of flexibility - in Objective-C an object can "capture" this message, and depending on the object, can send the message off again to a different object (who can respond to the message correctly and appropriately, or likewise send the message on again). This behaviour is known as message forwarding or delegation (see below). Alternatively, an error handler can be used instead, in case the message can not be forwarded. However if the object does not forward the message, handle the error, or respond to it, a runtime error occurs.

Like 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 specify the class of an object, and in such cases the compiler will apply static-typing methodology.

In an Objective-C function declaration, a special type, id, casts a parameter as a pointer to an object, without requiring that object to be of any class:

-(void)setMyValue:(id)aStringOrANumber;

If the programmer wants to require that the parameter is an object of a specific class, he can specify the type in the same way:

-(void)setMyValueToANumber:(NSNumber *)aNumber;

Perhaps most usefully, the programmer can allow the parameter to be dynamically-typed, but require that the parameter conform to a given protocol:

-(void)setMyValue:(id <ValueGivingProtocol>)anyObjectThatConforms;

When one does need dynamic typing, it becomes tremendously powerful. Consider a simple example, placing an object in a container. In statically-typed languages like C++ and Java, the programmer is forced to write a container class for a generic type of object, and then cast back and forth between the abstract generic type and the real type (note that C++ can also use templates for writing generic container classes). Sadly, casting breaks the discipline of static typing -- if you put in an Integer and read out a String, you get an error. 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 is a string coming back out just to call toUpperCase(). Dynamic typing removes this problem.

Forwarding

As mentioned, since Objective-C permits the sending of a message to an object that might not respond to it, the object has a number of things it can do with the message. One of these things could be to forward the message on to an object that can respond to it. Forwarding can be used to implement certain design patterns, such as the Observer design pattern or the Proxy design pattern very simply. See Examples of message forwarding in Objective-C for such an implementation.

The Objective-C runtime specifies a pair of methods in Object

  • forwarding methods:
- (retval_t) forward: (SEL) sel : (arglist_t) args; // with GCC
- (id) forward: (SEL) sel : (marg_list) args; // with NeXT/Apple systems
  • action methods:
- (retval_t) performv: (SEL) sel : (arglist_t) args;  // with GCC
- (id) performv: (SEL) sel : (marg_list) args; // with NeXT/Apple systems

and as such an object wishing to implement forwarding needs only to override the forwarding method to define the forwarding behaviour. The action methods performv:: need not be overriden as this method merely performs the method based on the selector and arguments.

Example

Here is an example of a program that demonstrates the basics of forwarding.

Forwarder.h
#import <objc/Object.h>

@interface Forwarder : Object
{
   id recipient; //The object we want to forward the message to. 
}

//Accessor methods
- (id) recipient: (id) _recipient; 
- (id) recipient;

@end
Forwarder.m
#import "Forwarder.h"

@implementation Forwarder

- (retval_t) forward: (SEL) sel : (arglist_t) args
{
   /*
    * Check whether the recipient actually responds to the message. 
    * This may or may not be desirable, for example, if a recipient
    * in turn does not respond to the message, it might do forwarding
    * itself.
    */
   if([recipient respondsTo:sel]) 
      return [recipient performv: sel : args];
   else
      return [self error:"Recipient does not respond"];
}

- (id) recipient: (id) _recipient
{
   recipient = _recipient;
   return self;
}

- (id) recipient
{
   return recipient;
}
@end
Recipient.h
#import <objc/Object.h>

// A simple Recipient object.
@interface Recipient : Object
- (id) hello;
@end
Recipient.m
#import "Recipient.h"

@implementation Recipient

- (id) hello
{
   printf("Recipient says hello!\n");

   return self;
}

@end
main.c
#import "Forwarder.h"
#import "Recipient.h"

int
main(void)
{
   Forwarder *forwarder = [Forwarder new];
   Recipient *recipient = [Recipient new];

   [forwarder recipient:recipient]; //Set the recipient. 
   /* 
    * Observe forwarder does not respond to a hello message! It will
    * be forwarded. All unrecognized methods will be forwarded to
    * the recipient 
    * (if the recipient responds to them, as written in the Forwarder)
    */
   [forwarder hello]; 

   return 0;
}

Notes

If we were to compile the program, the compiler would report that

$ gcc -x objective-c -Wno-import Forwarder.m Recipient.m main.c -lobjc
main.c: In function `main':
main.c:12: warning: `Forwarder' does not respond to `hello'
$

The compiler is reporting the point that was made earlier, Forwarders does not respond to hello messages. In certain circumstances, such a warning can help us find errors, but in this circumstance however, we can safely ignore this warning, since we have implemented forwarding. If we were to run the program

$ ./a.out
Recipient says hello!

For more examples, see examples of message forwarding in Objective-C

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 process.

A category collects method implementations into separate files. The programmer can place groups of related methods into a category to make them 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.

Furthermore, the methods within a category are added to a class at runtime. Thus, categories permit the programmer to add methods to an existing class without the need to recompile that class or even have access to its source code. For example, if the system you are supplied with does not contain a spell checker in its String implementation, you can add it without modifying the String source code.

Methods within categories become indistinguishable from the methods in a class when the program is run. A category has full access to all of the instance variables within the class, including private variables.

Categories provide an elegant solution to the fragile base class problem for methods.

If you declare a method in a category with the same method signature as an existing method in a class, the category's method is adopted. Thus categories can not only add methods to a class, but also replace existing methods. This feature can be used to fix bugs in other classes by rewriting their methods, or to cause a global change to a class's behavior within a program. If two categories have methods with the same method signature, it is undefined which category's method is adopted.

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 Self.

Example usage of categories

This example builds up an Integer class, by defining first a basic class with only accessor methods implemented, and adding two categories, Arithmetic and Display that extend the basic class. Whilst categories can access the base class's private data members, it is often good practice to access these private data members through the accessor methods, which helps keep categories more independent from the base class. This is one typical usage of categories -- the other is to use categories to add or replace certain methods in the base class (however it is not regarded as good practice to use categories for subclass overriding).

Integer.h
#include <objc/Object.h>

@interface Integer : Object
{
   int integer;
}

- (int) integer;
- (id) integer: (int) _integer;
@end
Integer.m
#import "Integer.h"

@implementation Integer
- (int) integer
{
   return integer;
}

- (id) integer: (int) _integer;
{
   integer = _integer;
}
@end
Arithmetic.h
#import "Integer.h"

@interface Integer (Arithmetic)
- (id) add: (Integer *) addend;
- (id) sub: (Integer *) subtrahend;
@end
Arithmetic.m
#import "Arithmetic.h"

@implementation Integer (Arithmetic) 
- (id) add: (Integer *) addend
{
   return [self integer: [self integer] + [addend integer]];
}

- (id) sub: (Integer *) subtrahend;
{
   return [self integer: [self integer] - [subtrahend integer]];
}
@end
Display.h
#import "Integer.h"

@interface Integer (Display)
- (id) showstars;
- (id) showint;
@end
Display.m
#import "Display.h"

@implementation Integer (Display) 
- (id) showstars
{
   int i, x = [self integer];
   for(i=0; i < x; i++)
      printf("*");
   printf("\n");

   return self;
}

- (id) showint
{
   printf("%d\n", [self integer]);

   return self;
}
@end


main.c
#import "Integer.h"
#import "Arithmetic.h" 
#import "Display.h"

int
main(void)
{
   Integer *num1 = [Integer new], *num2 = [Integer new];;
   int x;
   printf("Enter an integer: ");
   scanf("%d", &x);
   [num1 integer:x];
   [num1 showstars];
   printf("Enter an integer: ");
   scanf("%d", &x);
   [num2 integer:x];
   [num2 showstars];

   [num1 add:num2];
   [num1 showint];
}
Notes

Compliation is performed, for example, by

gcc -x objective-c main.c Integer.m Arithmetic.m Display.m -lobjc

You can experiment by omitting the #import "Arithmetic.h" and [num1 add:num2] lines and omit Arithmetic.m in compilation. The program will still run. This means that it is possible to "mix-and-match" added categories if necessary - if one does not need to have some capability provided in a category, one can simply not compile it in.

Posing

Objective-C permits a class to wholly replace another class within a program. The replacing class is said to "pose as" the target class. All messages sent to the target class are then instead received by the posing class. There are several restrictions on which classes can pose:

  • A class may only pose as one of its direct or indirect superclasses
  • The posing class must not define any new instance variables that are absent from the target class (though it may define or override methods).
  • No messages must have been sent to the target class prior to the posing.

Posing, similarly to categories, allows globally augmenting existing classes. Posing permits two features absent from categories:

  • A posing class can call overridden methods through super, thus incorporating the implementation of the target class.
  • A posing class can override methods defined in categories.

Other features

Objective-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.

  • Delegating methods to other objects at run-time is trivial. Simply add a category that changes the "second chance" method to forward the invocation to the delegate.
  • 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 where freed objects are swizzled into Zombies, whose only purpose is to report an error when someone calls them. Swizzling was also used in EOF to create database faults. Swizzling is used today by Apple's Foundation Framework to implement Key-Value Observing.
  • Archiving. An object can be archived into a stream, such as a file, and can be read and restored on demand.

Objective-C++

Objective-C++ is a front-end to the Mac OS X version of the GNU Compiler Collection that can compile source files that use both C++ and Objective-C, with certain restrictions:

  • A C++ class cannot derive from an Objective-C class and vice versa.
  • C++ namespaces cannot be declared inside an Objective-C declaration.
  • Objective-C classes cannot have instance variables of a C++ class type that has virtual functions, nor can C++ classes have instances of Objective-C objects.
  • An Objective-C declaration cannot be within a C++ template declaration and vice versa, though Objective-C classes can be used as C++ template parameters.

Today

Objective-C today is often used in tandem with a fixed library of standard objects (often known as a "kit" or "framework"), such as OpenStep/Cocoa/GNUstep. These libraries often come with the operating system - the OPENSTEP libraries come with the OPENSTEP operating system and Cocoa comes with Mac OS X. One can however bypass the framework and inherit directly from the root object, Object, and create one's own functionality. The aforementioned libraries however implement NSObject, a more technologically advanced version of Object.

History note: Earlier versions of NeXT's NeXTSTEP operating system had objects inheriting from Object, but migrated to the newer NSObject root class, which was named to distinguish it from the original Object root (see note on namespaces below). All newer versions of the NeXTSTEP libraries which had objects inheriting from NSObject were prefixed with "NS", whilst those which did not inherit from NSObject did not. Later, the entire library codebase as OpenStep moved to use the NSObject class outright, and to maintain compatibility with the NeXTSTEP libraries, the prefix was maintained, and is still maintained in Cocoa today. On the other hand, Cocoa has a class which does not inherit from NSObject: NSProxy.

Analysis of the language

Objective-C is a very "practical" language. Objective-C implementations use a thin runtime written in C that adds little to the size of the application. In contrast, most OO systems at the time that it was created used large VM runtimes that took over the entire system. Programs written in ObjC tend to be not much larger than the size of their code and that of the libraries (which generally don't need to be included in the software distribution), in contrast to Smalltalk systems where you needed huge amounts of memory just to open a window.

Likewise, the language can be implemented on top of existing C compilers (in the GCC, first as a preprocessor, then as a module) rather than as a new compiler. This allowed ObjC to leverage the huge existing collection of C code, libraries, tools, and mindshare. Existing C libraries - even in object code libraries - can be wrapped in ObjC wrappers to give them an OO style and more easily use them in your programs.

All of these practical changes lowered the barrier to entry, likely the biggest problem for the widespread acceptance of Smalltalk in the 1980s. In general Objective-C can be summed up as offering much of the flexibility of the later Smalltalk systems, in a language that is deployed as easily as C.

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. Objective-C avoided that problem by not including this feature. Some 3rd party implementations have added this feature (most notably GNUstep) and Apple has implemented an automatic garbage collector for Objective-C in Mac OS X 10.4, although still unfinished.

Another problem is that Objective-C does not have language support for namespaces. Instead programmers are forced to add prefixes to their class names, which often runs into collisions. As of 2004, all Mac OS X classes and functions in the Cocoa programming environment are prefixed with "NS" (as in NSObject or NSButton) to clearly identify them as belonging to the Mac OS X core; the "NS" derives from the names of the classes as defined during the development of NEXTSTEP.

Since Objective-C is a strict superset of C, it does not treat C primitive types as first-class objects either.

Objective-C does not support operator overloading (though it does support ad-hoc polymorphism), unlike the C++ language. Also, unlike C++, Objective-C allows an object only to directly inherit from one class (forbidding multiple inheritance). Since Java was influenced by Objective-C, this is also the case in Java. Categories and protocols may be used to provide many of the benefits of multiple inheritance, without many of the disadvantages, such as extra runtime overhead and binary incompatibilities.

External links

Template:Major programming languages smallda:Objective-C de:Objective-C es:Objective-C eo:Objective-C fr:Objective C ja:Objective-C pl:Objective C sk:Objective-C zh:Objective-C sv:Objective-C

Navigation

  • Art and Cultures
    • Art (https://academickids.com/encyclopedia/index.php/Art)
    • Architecture (https://academickids.com/encyclopedia/index.php/Architecture)
    • Cultures (https://www.academickids.com/encyclopedia/index.php/Cultures)
    • Music (https://www.academickids.com/encyclopedia/index.php/Music)
    • Musical Instruments (http://academickids.com/encyclopedia/index.php/List_of_musical_instruments)
  • Biographies (http://www.academickids.com/encyclopedia/index.php/Biographies)
  • Clipart (http://www.academickids.com/encyclopedia/index.php/Clipart)
  • Geography (http://www.academickids.com/encyclopedia/index.php/Geography)
    • Countries of the World (http://www.academickids.com/encyclopedia/index.php/Countries)
    • Maps (http://www.academickids.com/encyclopedia/index.php/Maps)
    • Flags (http://www.academickids.com/encyclopedia/index.php/Flags)
    • Continents (http://www.academickids.com/encyclopedia/index.php/Continents)
  • History (http://www.academickids.com/encyclopedia/index.php/History)
    • Ancient Civilizations (http://www.academickids.com/encyclopedia/index.php/Ancient_Civilizations)
    • Industrial Revolution (http://www.academickids.com/encyclopedia/index.php/Industrial_Revolution)
    • Middle Ages (http://www.academickids.com/encyclopedia/index.php/Middle_Ages)
    • Prehistory (http://www.academickids.com/encyclopedia/index.php/Prehistory)
    • Renaissance (http://www.academickids.com/encyclopedia/index.php/Renaissance)
    • Timelines (http://www.academickids.com/encyclopedia/index.php/Timelines)
    • United States (http://www.academickids.com/encyclopedia/index.php/United_States)
    • Wars (http://www.academickids.com/encyclopedia/index.php/Wars)
    • World History (http://www.academickids.com/encyclopedia/index.php/History_of_the_world)
  • Human Body (http://www.academickids.com/encyclopedia/index.php/Human_Body)
  • Mathematics (http://www.academickids.com/encyclopedia/index.php/Mathematics)
  • Reference (http://www.academickids.com/encyclopedia/index.php/Reference)
  • Science (http://www.academickids.com/encyclopedia/index.php/Science)
    • Animals (http://www.academickids.com/encyclopedia/index.php/Animals)
    • Aviation (http://www.academickids.com/encyclopedia/index.php/Aviation)
    • Dinosaurs (http://www.academickids.com/encyclopedia/index.php/Dinosaurs)
    • Earth (http://www.academickids.com/encyclopedia/index.php/Earth)
    • Inventions (http://www.academickids.com/encyclopedia/index.php/Inventions)
    • Physical Science (http://www.academickids.com/encyclopedia/index.php/Physical_Science)
    • Plants (http://www.academickids.com/encyclopedia/index.php/Plants)
    • Scientists (http://www.academickids.com/encyclopedia/index.php/Scientists)
  • Social Studies (http://www.academickids.com/encyclopedia/index.php/Social_Studies)
    • Anthropology (http://www.academickids.com/encyclopedia/index.php/Anthropology)
    • Economics (http://www.academickids.com/encyclopedia/index.php/Economics)
    • Government (http://www.academickids.com/encyclopedia/index.php/Government)
    • Religion (http://www.academickids.com/encyclopedia/index.php/Religion)
    • Holidays (http://www.academickids.com/encyclopedia/index.php/Holidays)
  • Space and Astronomy
    • Solar System (http://www.academickids.com/encyclopedia/index.php/Solar_System)
    • Planets (http://www.academickids.com/encyclopedia/index.php/Planets)
  • Sports (http://www.academickids.com/encyclopedia/index.php/Sports)
  • Timelines (http://www.academickids.com/encyclopedia/index.php/Timelines)
  • Weather (http://www.academickids.com/encyclopedia/index.php/Weather)
  • US States (http://www.academickids.com/encyclopedia/index.php/US_States)

Information

  • Home Page (http://academickids.com/encyclopedia/index.php)
  • Contact Us (http://www.academickids.com/encyclopedia/index.php/Contactus)

  • Clip Art (http://classroomclipart.com)
Toolbox
Personal tools