The Objective-C Language
************************

In the previous chapter you were introduced to some basic object-oriented programming terms. This chapter will expand on these terms, and introduce you to some new ones, while concentrating on how they apply to the Objective-C language and the GNUstep base library. First let us look at some non OO additions that Objective-C makes to ANSI C.

Non OO Additions
================

Objective-C makes a few non OO additions to the syntax of the C programming language that include:

  * A boolean data type (BOOL) capable of storing either of the values YES or NO.

     A BOOL is a scalar value and can be used like the familiar int and char data types.

     A BOOL value of NO is zero, while YES is non-zero.

  * The use of a pair of slashes (//) to mark text up to the end of the line as a comment.

  * The #import preprocessor directive was added, but its use is deprecated (it still works but it should not be used for new programs).

Objects
=======

Object-oriented (OO) programming is based on the notion that a software system can be composed of objects that interact with each other in a manner that parallels the interaction of objects in the physical world.

This model makes it easier for the programmer to understand how software works since it makes programming more intuitive. The use of objects also makes it easier during program design: take a big problem and consider it in small pieces, the individual objects, and how they relate to each other.

Objects are like mini programs that can function on their own when requested by the program or even another object. An object can receive messages and then act on these messages to alter the state of itself (the size and position of a rectangle object in a drawing program for example).

In software an object consists of instance variables (data) that represent the state of the object, and methods (like C functions) that act on these variables in response to messages.

As a programmer creating an application or tool, all you need do is send messages to the appropriate objects rather than call functions that manipulate data as you would with a procedural program.

The syntax for sending a message to an object, as shown below, is one of the additions that Objective-C adds to ANSI C.

     [objectName message];

Note the use of the square [ ] brackets surrounding the name of the object and message.

Rather than 'calling' one of its methods, an object is said to 'perform' one of its methods in response to a message. The format that a message can take is discussed later in this section.

Id and nil
----------

Objective-C defines a new type to identify an object: id, a type that points to an object's data (its instance variables). The following code declares the variable 'button' as an object (as opposed to 'button' being declared an integer, character or some other data type).

     id button;

When the button object is eventually created the variable name 'button' will point to the object's data, but before it is created the variable could be assigned the numeric value 0, to indicate to other code that the object does not yet exist.

Objective-C defines a new keyword nil for this assignment, where nil is of type id with the numeric value 0. In the button example, the assignment could look like this:

     id button = nil;

which assigns nil in the declaration of the variable.

You can then test the value of an object to determine whether the object exists, perhaps before sending the object a message. If the test fails, then the object does not exist and your code can execute an alternative statement.

     if (anObject != nil)
       ... /* send message */
     else ... /* do something else */

The header file objc/objc.h defines id, nil, and other basic types of the Objective-C language. It can be included in your source code with the compiler directive #include <Foundation/Foundation.h>.

Messages
--------

A message in Objective-C is the mechanism by which you pass instructions to objects.  You may tell the object to do something for you, tell it to change its internal state, or ask it for information.

A message usually invokes a method, causing the receiving object to respond in some way. Objects and data are manipulated by sending messages to them. Like C-functions they have return types, but function specific to the object.

Objects respond to messages that make specific requests. Message expressions are enclosed in square brackets and include the receiver or object name and the message or method name along with any arguments.

To send a message to an object, use the syntax:

[receiver messagename];

where receiver is the object.

The run-time system invokes object methods that are specified by messages. For example, to invoke the display method of the mySquare object the following message is used:

[mySquare display];

Messages may include arguments that are prefixed by colons, in which case the colons are part of the message name, so the following message is used to invoke the setFrameOrigin:: method:

[button setFrameOrigin: 10.0 : 10.0];

Labels describing arguments precede colons:

[button setWidth: 20.0 height: 122.0]; invokes the method named setWidth:height:

Messages that take a variable number of arguments are of the form:

[receiver makeList: list, argOne, argTwo, argThree];

A message to nil does NOT crash the application (while in Java messages to null raise exceptions); the Objective-C application does nothing.

For example:

[nil display];

will do nothing.

If a message to nil is supposed to return an object, it will return nil. But if the method is supposed to return something else, then the return value of that method when invoked on nil, is undefined. The programmer therefore needs to avoid using the return value in this instance.

Polymorphism
------------

Polymorphism refers to the fact that two different objects may respond differently to the same message. For example when client objects receive an alike message from a server object, they may respond differently. Using Dynamic Binding, the run-time system determines which code to execute according to the object type.

Classes
=======

needs to be clearer/readable and say what a class is? also explain
instances!

Objects form groups or classes, and those in the same class hold the same type of data, and may execute the same methods. Objects are defined by their originating classes. Each class compilation sees the creation of a factory or class object that builds instances of the class. Instances and Objects are synonymous, and are the components that are operating entities in the running program.

Inheritance
-----------

Most of the programmer's time is spent defining classes. Inheritance helps reduce coding time by providing a convenient way of reusing code. For example, the NSButton class defines data (or instance variables) and methods to create button objects of a certain type, so a subclass of NSButton could be produced to create buttons of another type - which may perhaps have a different border colour. Equally NSTextField can be used to define a subclass that perhaps draws a different border, by reusing definitions and data in the superclass.

Inheritance places all classes in a logical hierarchy or tree structure that may have the NSObject class at its root. All classes may have subclasses, and all except the root class may have superclasses. When a class object creates a new instance, the new object holds the data for its class, superclass, and superclasses extending to the root class (typically NSObject). Additional data may be added to classes so as to provide specific functions and application logic.

When a new object is created, it is allocated memory space, and its data in the form of its instance variables are initialised. The object holds the isa variable refers to the object's class, and this also provides access to classes in the object's inheritance path.

An Objective-C class has an:

  * interface declaring instance variables, methods and the superclass name.

  * implementation that defines the class in terms of operational code that implements the methods.

Typically these entities are confined to separate files with .h and .m extensions for Interface and Implementation files, respectively. However they may be merged into one file, and a single file may implement multiple classes.

Inheritance of Methods
----------------------

Each new class inherits methods and instance variables from another class. This results in a class hierarchy with the root class at the core, and every class (except the root) has a superclass as its parent, and all classes may have numerous subclasses as their children. Each class therefore is a refinement of its superclass(es).

Overriding Methods
------------------

Objects may access methods defined for their class, superclass, superclass' superclass, extending to the root class. Classes may be defined with methods that overwrite their namesakes in ancestor classes. These new methods are then inherited by subclasses, but other methods in the new class can locate the overridden methods. Additionally redefined methods may include overridden methods.

Abstract Classes
----------------

Abstract classes or abstract superclasses such as NSObject define methods and instance variables used by multiple subclasses. Their purpose is to reduce the development effort required to create subclasses and application structures. When we get technical, we make a distinction between a pure abstract class whose methods are defined but instance variables are not, and a semi-abstract class where instance variables are defined). An abstract class is not expected to actually produce functional instances since crucial parts of the code are expected to be provided by subclasses. Abstract classes reduce the development effort required to create subclasses and application structures.

Class Clusters
--------------

A class cluster is an abstract base class, and a group of private, concrete subclasses.  It is used to hide implementation details from the programmer (who is only allowed to use the interface provided by the abstract class), so that the actual design can be modified (probably optimised) at a later date, without breaking any code that uses the cluster. Consider a scenario where it is necessary to create a class hierarchy to define objects holding different types including chars, ints, short, LongInt, floats and doubles. Of course, different types could be defined in the same class since it is possible to cast or change them from one to the next. Their allocated storage differs, however, so it would be inefficient to bundle them in the same class and to convert them in this way.

The solution to this problem is to use a class cluster: define an abstract superclass that specifies and declares components for subclasses, but does not declare instance variables. Rather this declaration is left to its subclasses, which share the programmatic interface that is declared by the abstract superclass.

When you create an object using a cluster interface, you are given an object of another class - from a concrete class in the cluster.

Using the GNUstep Base Library
==============================

*** Add something here about using the base library. Some suggestions:

Explain class documentation, what it is (documented class interface that programmers can use), how to use it (the need to read it and comply with the  interface methods and arguments), and how to get it (www.gnustep.org).

Also explain some of the terminology, like 'returns a copy of the receiving object'. ***

NSObject: The Root Class
========================

NSObject is a root class that provides the framework for all objects, their interactions, and their integration in the run-time system. NSObject defines the isa instance variable that connects every object with its class NSObject or an alternative root class:

  * allocates instances

  * connects instances to their class

  * forces the run-time system to discover instances involuntarily.

The NSObject interface is defined as the methods declared by itself, and those defined by the NSObject protocol. This division ensures that objects inheriting from other root classes can act as ordinary objects that do not inherit from NSObject. NSObject provides the facilities for inheriting classes whose instances are given a behaviour that includes the ability to:

  * create objects.

  * initialize objects.

  * deallocate objects.

  * compare objects.

  * archive objects.

  * perform methods selected at run-time.

  * query objects about their methods.

  * query objects about their position in the inheritance hierarchy.

  * forward messages to other objects (See Section respondsToSelector).

Initializing Objects
--------------------

All objects inherit from the NSObject class, and their initialization requires:

  * an isa instance variable that points to a class structure.

  * initialization of isa is performed by alloc and allocWithZone: methods that are also used to create (allocate memory for) new instances of classes.

Static Typing
=============

Type checking is good programming practice because it catches errors; it checks code, but does not change compiled code.

When declaring an object type, static typing permits a class name to be used instead of an id. In the following example Type Checking verifies that the myString object is an appropriate type.

     NSString *myString = anObject;

Objects can be statically typed as pointers to a class, by making the pointer explicit (as opposed to hidden using id). Static typing permits the compiler to run some obvious checks, forewarning of such errors as message incompatibilities. A subclass can be used where a superclass is expected, but not vice-versa.

Formal protocols may be included in type definitions, giving another tier of type checking to the compiler. Protocol names are included between angle brackets:

     - (id <Formatting>) formattingService;
     id <ReferenceCounting,AutoFreeing> specificObject;

Formal protocols may declare a list of methods that are visible at source and run-time levels, so objects may introspect themselves at runtime to verify that they conform to protocols, and the compiler may check for types:

     @protocol ProtocolTitle
     declare methods
     @end

Type Introspection
------------------

Before sending a message you should check that the receiver is the correct class or has the appropriate method. The isMemberOfClass: method defined in the NSObject class verifies that the receiver is of a specific class:

     if ([namedObject isMemberOfClass: specificClass] == YES)
     {
       // code here
     }

The isKindOfClass: method checks to see if the receiver is in a specific inheritance path:

     if ([namedObject isKindOfClass: specificClass] == YES)
     {
       // code here
     }

Working with Class Objects
==========================

The compiler creates a class or factory object that instantiates objects or instances based on the class definitions; class objects are agents able to instantiate instances in the run-time system. A class object is not an instance and is without instance variables, though it does holds static variables and the class instance's prototype also; but it cannot implement methods for instances of the class.

A class definition may include class methods that are defined for the class object. A class object inherits class methods from superclasses, while instances inherit instance methods. Class objects may receive messages, and inherit methods from superclasses, but are without instance variables except those created using the class definition.

Referring to Class Objects
--------------------------

To return the class version number of the NSString class using a method inherited from the NSObject class:

int versionNumber = [NSString version];

The class name NSString is that of the class object, which is the receiver in the above message expression. When not dealing with class objects, instances and classes are used to obtain the class id:

     id stringClass = [stringObject class];
     id mStringClass = [NSMutableString class];

Class objects may be typed id, and specifically typed to the Class:

     Class stringClass = [stringObject class];
     Class mStringClass = [NSMutableString class];

Class objects are of the type Class, rather like the class name is used to statically type instances.

Creating Instances
------------------

Class objects create new instances; to use the NSDate class to create a new NSDate instance and assign it to the date variable:

     id date;
     date = [NSDate alloc];

The alloc method equates the object's instance variables to zero with the exception of the isa variable, and also allocates memory for them. Complete initialisation of the object however relies on the init method that primes 'date' to receive messages:

date = [[NSDate alloc] init];

The alloc method returns a new instance that implements the init method, and like all instances and class objects it holds at least one method. The init method may take arguments so as to pass values.

Factory Patterns
----------------

Nicola to complete

(To be completed.)

Factory or Class Objects
------------------------

Each class compilation sees the creation of a factory object or class object that builds class-specific objects. Objects instantiated by the factory object at run-time are instances of the class. Class names begin with an uppercase letter, while instance names begin with lowercase letter.

The compiler may create as many class objects as there are defined classes. The class objects are conventional objects that may be dynamically typed, receivers, and the recipients of class methods in superclasses.

NSClassFromString
-----------------

Class names are about the only names with global visibility in Objective-C. If a class is unknown at compilation but is available as a string at run time, NSClassFromString may be used to return the class object:

     ..
     if ([anObject isKindOf: NSClassFromString(classTitle)] == YES)
     ..

The function returns nil if it is passed a string holding an invalid class name. Class names, global variables and function exist in the same name space, so classes and global variables may not share the same name.

respondsToSelector and NSStringFromClass
----------------------------------------

Run-time errors result when objects are stimulated to perform methods absent from their repertoire. These errors are avoided by checking the receiver's available methods, and if statically typed the compiler will report them. Testing for this error may be left until run-time when the message selector or the receiver's class varies. The respondsToSelector: method inspects a receiver for compatibility by sending them the method selector as an argument, and subsequently returning a verification.

     if ([userObject respondsToSelector: @selector(setOrigin::)] == YES)
       {
         [userObject setOrigin: 2.0 : 2.0];
       }
     else
       {
         NSLog(% out of range", NSStringFromClass([userObject class]));
       }

Naming Conventions
==================

  * Global variables may NOT share the same name as classes, because both entities are allocated the same name space.

  * Files with an .m extension hold Objective-C source code, while those with a .h extension define protocols, or define classes and category interfaces.

  * Implementation files have an .m extension.

  * Interface files have a .h extension.

  * Class, category and protocol names begin with an uppercase letter.

  * Methods, instance variables, and variables holding instances begin with a lowercase letter.

  * A class may define methods using the same names as those held in other classes. (See Overriding Methods.)

  * A class may define instance variables using the same names as those held in other classes.

  * A class category may have the same name as another class category.

  * An instance method and a class method may share the same name.

  * A protocol may have the same name as a class, category, or any other entity.

  * A method and an instance variable may share the same name.

Pitfalls of Using Class Names
-----------------------------

Richard to complete

(To be completed.)

The NSString Class
==================

The NSString class defines objects holding character streams or strings using any spoken language. A static instance of NSString is allocated at compile time. The creation of a static instance of NSString is achieved using the @"..." construct and a pointer:

     NSString *wasp = @"Brainstorm";

wasp is a variable that refers to an NSString object representing the ASCII string "Brainstorm".