Objective-C: differenze tra le versioni
Contenuto cancellato Contenuto aggiunto
+Bibliografia |
Inserito testo da tradurre da en:wiki |
||
Riga 33:
L'objective c funziona grazie ad un'interfaccia (scritta in un file ".h") ed una implementazione (scritta in un file ".m"). In alcuni casi queste due parti vengono scritte nello stesso script separate dai tag @interface e @implementation.
==Sintassi==
{{T sezione|lingua=inglese|argomento=informatica|data=febbraio 2008}}
l'Objective C è un sottile strato posto ''sopra'' il [[linguaggio C]]; C quindi è uno [[sottoinsieme]] stretto dell'Objective C. Ne consegue che è possibile compilare un qualsiasi programma scritto in C con un compilatore Objective C. La gran parte della [[sintassi]] (clausole del [[preprocessore]], [[espressione (informatica)|espressioni]], [[funzione (informatica)|dichiarazioni e chiamate di funzioni]]) è derivata da quella del C, mentre la sintassi relativa alle caratteristiche [[object-oriented]] è stata creata per ottenere la [[comunicazione a scambio di messaggi]] simile a quella di [[Smalltalk]].
===Messaggi===
la sintassi aggiunta rispetto al C è intesa al supporto della programmazione ad oggetti. Il modello di programmazione dell'Objective C è basato sullo scambio di messaggi tra oggetti così come avviene in Smalltalk. Tale modello è differente da quello di [[Simula]], che viene usato in numerosi linguaggi quali, tra gli altri, il [[C++]]. Questa distinzione è [[semantica (informatica)|semanticamente]] importante e consiste principalmente nel fatto che in Objective C non si ''chiama un [[metodo (programmazione)|metodo]]'', ma si ''invia un [[messaggio]]''.
Si dice che un oggetto chiamato ''ogg'' la cui [[classe (informatica)|classe]] implementa il metodo ''faiQualcosa'', ''risponde'' al messaggio ''faiQualcosa''. L'invio del messaggio ''faiQualcosa'' all'oggetto ''ogg'' è espresso da:
<source lang="objc">[ogg faiQualcosa];</source>
mentre l'azione equivalente in C++ sarebbe espressa da:
<source lang="cpp">ogg.faiQualcosa;</source>
In questo modo è possibile inviare messaggi ad un oggetto anche se l'oggetto ''non è capace'' di rispondere. Questo differisce dai linguaggi [[tipo di dato|tipizzati]] staticamente come C++ e [[Java (linguaggio)|Java]] nei quali tutte le chiamate devo essere di metodi predefiniti.
===Interfacce e implementazioni===
l'Objective C richiede che l'[[interfaccia]] e l'[[implementazione]] di una classe siano dichiarati in blocchi di codice differenti. Per convenzione l'interfaccia è messa in un file con suffisso ".h", mentre l'implementazione in un file con suffisso ".m".
====Interfaccia====
L'interfaccia di una classe è solitamente definita in un file ".h". La convenzione usata è quella di assegnare il nome al file basandosi sul nome della classe, nell'esempio "NomeDellaClasse.h".
<source lang="objc">
//definizione dell'interfaccia: "NomeDellaClasse.h"
#import "
@interface
{
//
int variabileIntera;
float variabileFloat;
}
//metodi di classe
+ metodoDiClasse1
+ metodoDiClasse2
+ ...
//
- metodoDiIstanza1
- metodoDiIstanza2
- ...
@end
</source>
Il segno meno (-) denota i metodi d'istanza, mentre il segno più (+) quello di classe (analoghi alle funzioni statiche del C++). Si noti la differenza di significato con le convenzioni dei [[Unified Modeling Language|diagrammi UML]] dove i due segni rappresentano rispettivamente i metodi privati e pubblici.
====Implementazione====
L'interfaccia dichiara solamente i [[prototipo|prototipi]] dei metodi e non i metodi stessi che vengono inseriti nell'implementazione. L'implementazione è solitamente scritta in un file con estensione ".m".
La convenzione usata è quella di assegnare il nome al file basandosi sul nome della classe, nell'esempio "NomeDellaClasse.m"
<source lang="objc">
//definizione dell'implementazione: "NomeDellaClasse.m"
#import
@implementation
+ metodoDiClasse1
{
// implementazione
...
}
+ metodoDiClasse2
{
// implementazione
}
...
- metodoDiIstanza1
{
// implementazione
...
}
- metodoDiIstanza2
{
// implementazione
...
}
...
@end
</source>
I metodi sono scritti in maniera diversa dalle [[funzione (informatica)|funzioni]] in stile C. Ad esempio, una funzione, sia in C che in Objective C segue la seguente forma generale:
<source lang="objc">
int fai_la_radice_quadrata(int i)
{
return radice_quadrata(i);
}
</source>
che avrà come prototipo:
<source lang="objc">int fai_la_radice_quadrata(int);</source>
L'implementazione come metodo diverrà:
<source lang="objc">
- (int) fai_la_radice_quadrata:(int) i
{
return [self radice_quadrata: i];
}
</source>
Un approccio più canonico alla scrittura del metodo sarebbe quello di citare il primo argomento nel nome del selettore:
<source lang="objc">
- (int) faiLaRadiceQuadrataDiInt: (int) i
{
return [self radiceQuadrataDiInt:i];
}
</source>
Questa sintassi può apparire complicata, ma consente di assegnare i nomi ai [[parametro (informatica)|parametri]], ad esempio:
<source lang="objc">
- (int) changeColorWithRed:(int) r green:(int) g blue:(int) b
</source>
può essere invocato così:
<source lang="objc">
[myColor changeColorWithRed:5 green:2 blue:6];
</source>
Le rappresentazioni interne di questi metodi possono variare con le diverse implementazioni di Objective C.
Se ''MyColor'', nell'esempio precedente, fosse della classe ''Color'', internamente il metodo d'istanza ''-changeColorWithRed:green:blue:'' potrebbe essere etichettato ''_i_Color_changeColorWithRed_green_blue'', dove ''i'' seguito dal nome della classe, si riferisce al fatto che è un metodo d'istanza ed i due punti (:) sono sostituiti dal [[trattino basso]] (_). Dato che l'ordine dei parametri fa parte del nome del metodo, esso non può essere cambiato.
In ogni caso i nomi interni delle funzioni sono usati raramente in maniera diretta e generalmente anche i messaggi inviati sono convertiti in funzioni definite in librerie di [[run-time]] e non accedono direttamente ai nomi interni. Ciò è dovuto anche al fatto che al momento della [[compilazione]] non sempre si conosce quale metodo sarà effettivamente chiamato, perché la classe del destinatario (l'oggetto a cui viene inviato il messaggio) potrebbe essere sconosciuta fino al run-time.
<!--
=== 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 either as an abstract multiply inherited base class in C++, or else, more popularly, adopted (e.g., in Java or C#) 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 which 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 which should implement an informal protocol with an optional autocomplete method. The text field discovers whether the delegate implements that method (via [[Reflection (computer science)|reflection]]), and, if so, calls it to support autocomplete.
A formal protocol is similar to an interface in Java or C#. It is a list of methods which 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 Objective-C concept of protocols is different from the Java or C# concept of interfaces in that a class may implement a protocol without being declared to implement that protocol. The difference is not detectable from outside code. Formal protocols cannot provide any implementations, they simply assure callers that classes which conform to the protocol will provide implementations. In the NeXT/Apple library, protocols are frequently used by the Distributed Objects system to represent the capabilities of an object executing on a remote system.
The syntax
<source lang="objc">
@protocol Locking
- (void)lock;
- (void)unlock;
@end
</source>
denotes that there is the abstract idea of locking which is useful, and when stated in a class definition
<source lang="objc">
@interface SomeClass : SomeSuperClass <Locking>
@end
</source>
denotes 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 the desired behaviors of plug-ins for example, without constraining at all what the implementation hierarchy should be.
===Dynamic typing===
Objective-C, like Smalltalk, can use [[dynamic typing]]; we can send an object a message not specified in its interface. This can allow for increased 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 behavior is known as ''message forwarding'' or ''delegation'' (see below). Alternatively, an error handler can be used instead, in case the message cannot be forwarded. If the object does not forward the message, handle the error, or respond to it, a [[runtime]] error occurs.
Static typing information may also optionally be added to variables. This information is then checked at compile time. In the following statements, increasingly specific type information is provided. The statements are equivalent at runtime, but the additional information allows the compiler to warn the programmer if the passed argument does not match the type specified. In the first statement, the object must conform to the ''aProtocol'' protocol, and in the second, it must be a member of the NSNumber class.
<source lang="objc">
- setMyValue:(id <aProtocol>) foo;
- setMyValue:(NSNumber*)foo;
</source>
Dynamic typing can be a powerful feature. When implementing container classes using statically-typed languages without generics like pre-1.5 Java, the programmer is forced to write a [[Container (data structure)|container class]] for a generic type of object, and then cast back and forth between the abstract generic type and the real type. [[Type conversion|Casting]] however breaks the discipline of [[Type system#Static and dynamic typing|static typing]] – if you put in an [[Integer]] and read out a [[String (computer science)|String]], you get an error. One way of alleviating the problem is to resort to [[generic programming]], but then container classes must be homogeneous in type. This need not be the case with dynamic typing.
=== Forwarding ===
Since Objective-C permits the sending of a message to an object which 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 which can respond to it. Forwarding can be used to implement certain [[design pattern (computer science)|design patterns]], such as the [[Observer pattern]] or the [[Proxy pattern]] very simply.
The Objective-C runtime specifies a pair of methods in <tt>Object</tt>
* forwarding methods:
<source lang="objc">
- (retval_t) forward:(SEL) sel :(arglist_t) args; // with GCC
- (id) forward:(SEL) sel :(marg_list) args; // with NeXT/Apple systems
</source>
* action methods:
<source lang="objc">
- (retval_t) performv:(SEL) sel :(arglist_t) args; // with GCC
- (id) performv:(SEL) sel :(marg_list) args; // with NeXT/Apple systems
</source>
and as such an object wishing to implement forwarding needs only to override the forwarding method to define the forwarding behaviour. The action methods <tt>performv::</tt> need not be overridden as this method merely performs the method based on the selector and arguments.
==== Example ====
Here is an example of a program which demonstrates the basics of forwarding.
; ''Forwarder.h''
<source lang="objc">
#import <objc/Object.h>
@interface Forwarder : Object
{
id recipient; //The object we want to forward the message to.
}
//Accessor methods
- (id) recipient;
- (void) setRecipient:(id) _recipient;
@end
</source>
; ''Forwarder.m''
<source lang="objc">
#import "Forwarder.h"
@implementation Forwarder
- forward: (SEL) sel : (marg_list) 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) setRecipient: (id) _recipient
{
recipient = _recipient;
return self;
}
- (id) recipient
{
return recipient;
}
@end
</source>
; ''Recipient.h''
<source lang="objc">
#import <objc/Object.h>
// A simple Recipient object.
@interface Recipient : Object
- (id) hello;
@end
</source>
; ''Recipient.m''
<source lang="objc">
#import "Recipient.h"
@implementation Recipient
- (id) hello
{
printf("Recipient says hello!\n");
return self;
}
@end
</source>
; main.m
<source lang="objc">
#import "Forwarder.h"
#import "Recipient.h"
int
main(void)
{
Forwarder *forwarder = [Forwarder new];
Recipient *recipient = [Recipient new];
[forwarder setRecipient: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;
}
</source>
==== Notes ====
If we were to compile the program, the compiler would report
$ gcc -x objective-c -Wno-import Forwarder.m Recipient.m main.m -lobjc
main.m: In function `main':
main.m:12: warning: `Forwarder' does not respond to `hello'
$
The compiler is reporting the point made earlier, that <tt>Forwarder</tt> does not respond to hello messages. In certain circumstances, such a warning can help us find errors, but in this circumstance, we can safely ignore this warning, since we have implemented forwarding. If we were to run the program
$ ./a.out
Recipient says hello!
===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’ 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 (object-oriented programming language)|TOM]] took the Objective-C system a step further and allowed for the addition of variables as well. Other languages have instead used [[Prototype-based programming|prototype oriented]] solutions, the most notable being [[Self programming language|Self]].
==== Example usage of categories ====
This example builds up an <tt>Integer</tt> class, by defining first a basic class with only [[Method (computer science)|accessor method]]s implemented, and adding two categories, <tt>Arithmetic</tt> and <tt>Display</tt>, which extend the basic class. Whilst categories can access the base class’ 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''
<source lang="objc">
#include <objc/Object.h>
@interface Integer : Object
{
int integer;
}
- (int) integer;
- (id) integer: (int) _integer;
@end
</source>
; ''Integer.m''
<source lang="objc">
#import "Integer.h"
@implementation Integer
- (int) integer
{
return integer;
}
- (id) integer: (int) _integer
{
integer = _integer;
}
@end
</source>
; ''Arithmetic.h''
<source lang="objc">
#import "Integer.h"
@interface Integer (Arithmetic)
- (id) add: (Integer *) addend;
- (id) sub: (Integer *) subtrahend;
@end
</source>
; ''Arithmetic.m''
<source lang="objc">
#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
</source>
; ''Display.h''
<source lang="objc">
#import "Integer.h"
@interface Integer (Display)
- (id) showstars;
- (id) showint;
@end
</source>
; ''Display.m''
<source lang="objc">
#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
</source>
; ''main.m''
<source lang="objc">
#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];
}
</source>
==== Notes ====
Compilation is performed, for example, by
gcc -x objective-c main.m Integer.m Arithmetic.m Display.m -lobjc
One can experiment by omitting the <tt>#import "Arithmetic.h" </tt> and <tt>[num1 add:num2]</tt>
lines and omit <tt>Arithmetic.m</tt> 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 which 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.
For example,
<source lang="objc">
@interface CustomNSApplication : NSApplication
@end
@implementation CustomNSApplication
- (void) setMainMenu: (NSMenu*) menu
{
// do something with menu
}
@end
class_poseAs ([CustomNSApplication class], [NSApplication class]);
</source>
This intercepts every invocation of setMainMenu to NSApplication.
However, class posing was declared deprecated with MacOS X 10.5 (Leopard) and unavailable in the 64-bit runtime.
===#import===
In the C language, the ''#include'' pre-compile directive allows for the insertion of entire files before any compilation actually begins. Objective-C adds the ''#import'' directive, which does the same thing, except that it knows not to insert a file which has already been inserted.
For example, if file A includes files X and Y, but X and Y each include the file Q, then Q will be inserted twice into the resultant file, causing "duplicate definition" compile errors. But if file Q is included using the ''#import'' directive, only the first inclusion of Q will occur—all others will be ignored.
A few compilers, including [[GNU Compiler Collection|GCC]], support ''#import'' for C programs too; its use is discouraged on the basis that the ''user'' of the header file has to distinguish headers which should be included only once, from headers designed to be used multiple times. It is argued that this burden should be placed on the implementor; to this end, the implementor may place the directive ''#[[pragma once]]'' in the header file, or use the traditional ''[[include guard]]'' technique:
#ifndef HEADER_H
#define HEADER_H
... contents of header.h ...
#endif
If a header file uses guards or ''#pragma once'', it makes no difference whether it is ''#include''d or ''#import''ed. The same objection to ''#import'' actually applies to Objective-C as well, and many Objective-C programs also use guards in their headers.
== Other features ==
Objective-C has from the beginning included a list of features which are still being added to other languages, and some which are unique to it. 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 which changes the "second chance" method to forward the invocation to the delegate.
* [[Remote procedure call|Remote invocation]] is trivial. Simply add a category which changes the "second chance" method to serialize the invocation and forward it off.
* [[Swizzling]] of the <var>isa</var> pointer allows for classes to change at runtime. Typically used for [[debugging]] where freed objects are swizzled into zombie objects, whose only purpose is to report an error when someone calls them. Swizzling was also used in [[Enterprise Objects Framework|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 [[GNU Compiler Collection]] which can compile source files which use a combination of C++ and Objective-C syntax. Objective-C++ adds to C++ the extensions Objective-C adds to C. As nothing is done to unify the semantics behind the various language features, certain restrictions apply:
* 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 C++ classes which do not have a default constructor or which have one or more virtual methods, but pointers to C++ objects can be used as instance variables without restriction (allocate them with new in the -init method).
* C++ "by value" semantics cannot be applied to Objective-C objects, which are only accessible through pointers.
* An Objective-C declaration cannot be within a C++ template declaration and vice versa. Objective-C types, (e.g., Classname *) can be used as C++ template parameters, however.
* Objective-C and C++ exception handling is distinct; the handlers of each cannot handle exceptions of the other type.
* Care must be taken since the destructor calling conventions of Objective-C and C++’s exception run-time models do not match (i.e., a C++ destructor will not be called when an Objective-C exception exits the C++ object’s scope).
==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 Cocoa or GNUstep. These libraries often come with the operating system: the GNUstep libraries often come with [[Linux distribution]]s and Cocoa comes with Mac OS X. The programmer is not forced to inherit functionality from the existing base class (NSObject). Objective-C allows for the declaration of new root classes which do not inherit any existing functionality. Originally, Objective-C based programming environments typically offered an Object class as the base class from which almost all other classes inherited. With the introduction of OpenStep, NeXT created a new base class named NSObject which offered additional features over Object (an emphasis on using object references and reference counting instead of raw pointers, for example). Almost all classes in Cocoa inherit from NSObject.
Not only did the renaming serve to differentiate the new default behavior of classes within the OpenStep API, but it allowed code which used Object — the original base class used on NeXTSTEP (and, more or less, other Objective-C class libraries) — to co-exist in the same runtime with code which used NSObject (with some limitations). As well, the introduction of the two letter prefix became a sort of simplistic form of namespaces, which Objective-C lacks. Using a prefix to create an informal packaging identifier became an informal coding standard in the Objective-C community, and continues to this day.
===Objective-C 2.0===
At the 2006 [[Worldwide Developers Conference]], Apple Computer announced the forthcoming release of "Objective-C 2.0". Apple has announced that "modern garbage collection, syntax enhancements[http://lists.apple.com/archives/Objc-language/2006/Aug/msg00039.html], runtime performance improvements[http://lists.apple.com/archives/Objc-language/2006/Aug/msg00018.html], and 64-bit support" will be available[http://developer.apple.com/leopard/overview/tools.html]. It is not yet known when these language improvements will be available in the GNU runtime, although Apple already supports it in Mac OS X Leopard.[http://www.apple.com/macosx/features/300.html#xcode3].
====Garbage collection====
Objective-C 2.0 allows for garbage collection, but it is an opt-in system. One may use garbage collection in a backwards compatible way, such that code written for previous versions will continue to work.
====Properties====
Whereas instance variables previously required the creation of methods to get and set (getters and setters) those variables, Objective-C 2.0 introduces the property syntax:
<source lang="objc">
@interface Person : NSObject {
}
@property(readonly) NSString *name;
@property(readonly) int age;
-(id)initWithName:(NSString)name age:(int)age;
@end
</source>
Once added to the interface, properties can be accessed using dot notation (example given an instance aPerson of the above Person class):
NSString *name = aPerson.name;
The compiler translates property dot notation into accessor method calls. The above statement is equivalent to:
NSString *name = [aPerson name];
====Fast Enumeration====
Instead of using an Enumerator object to iterate through a collection, Objective-C 2.0 offers the foreach syntax (given an array thePeople of objects of the above defined Person):
<source lang="objc">
for (Person *person in thePeople)
NSLog(@"%@ is %i years old.", person.name, person.age);
</source>
=== Portable Object Compiler ===
Besides the [[GNU Compiler Collection|GCC]]/[[NeXT]]/[[Apple Computer]] implementation, which added several extensions to the original [[Stepstone]] implementation, there exists another free open-source Objective-C implementation, which implements a slightly different set of extensions: The Portable Object Compiler [http://users.pandora.be/stes/compiler.html] implements, among other things, also [[Smalltalk]]-like blocks for Objective-C.
== Analysis of the language ==
Objective-C implementations use a thin [[runtime]] written in C which adds little to the size of the application. In contrast, most OO systems at the time that it was created (and Java even today) used large [[virtual machine|VM]] runtimes which took over the entire system. Programs written in Objective-C tend to be not much larger than the size of their code and that of the libraries (which generally do not need to be included in the [[software distribution]]), in contrast to Smalltalk systems where a large amount of memory was used just to open a window.
Likewise, the language can be implemented on top of existing C compilers (in [[GNU Compiler Collection|GCC]], first as a preprocessor, then as a module) rather than as a new compiler. This allows Objective-C 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 Objective-C [[Adapter pattern|wrappers]] to provide an OO-style interface.<br>
All of these practical changes lowered the [[Barriers to entry|barrier to entry]], likely the biggest problem for the widespread acceptance of Smalltalk in the 1980s.
The first versions of Objective-C did not support [[garbage collection (computer science)|garbage collection]]. At the time this decision was a matter of some debate, and many people considered long "dead times" (when Smalltalk did collection) to render the entire system unusable. Although some 3rd party implementations have added this feature (most notably GNUstep), Apple implemented it as of [[Mac OS X v10.5]]. But it is unavailable to applications targeting older versions of the Mac OS<ref>{{cite web|url=http://www.apple.com/macosx/developertools/xcode.html|title=Mac OS X Leopard – Xcode 3.0|author=Apple, Inc.|year=[[August 22]] [[2006]]|=publisher=apple.com|accessdate=2006-08-22}}</ref>
Another common criticism is that Objective-C does not have language support for [[Namespace (computer science)|namespaces]]. Instead programmers are forced to add prefixes to their class names, which can cause collisions. As of [[2007]], all Mac OS X classes and functions in the [[Cocoa (software)|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 object]]s either.
Unlike [[C++]], Objective-C does not support [[operator overloading]]. Also unlike C++, Objective-C allows an object only to directly inherit from one class (forbidding [[multiple inheritance]]). As Java was influenced by the design of Objective-C, the decision to use single inheritance was carried into Java. Categories and protocols may be used as alternative functionality to multiple inheritance; Java however lacks categories.
=== Philosophical differences between Objective-C and C++ ===
The design and implementation of [[C++]] and Objective-C represent different approaches to extending C.
In addition to C’s style of procedural programming, C++ directly supports [[object-oriented programming]], [[generic programming]], and [[metaprogramming]]. C++ also comes with a large standard library which includes several [[Container (data structure)|container classes]]. Objective-C, on the other hand, adds only object-oriented features to C. Objective-C in its purest fashion does not contain the same number of standard library features, but in most places where Objective-C is used, it is used with an [[OpenStep]]-like library such as [[OPENSTEP]], [[Cocoa (API)|Cocoa]], or [[GNUstep]] which provide similar functionality to some of C++’s standard library.
One notable difference is that Objective-C provides runtime support for some [[reflection (computer science)|reflective]] features, whereas C++ adds only a small amount of runtime support to C. In Objective-C, an object can be queried about its own properties, for example whether it will respond to a certain message. In C++ this is not possible without the use of external libraries; however, it is possible to query whether two objects are of the same type (including built-in types) and whether an object is an instance of a given class (or [[superclass (computer science)|superclass]]).
The use of reflection is part of the wider distinction between dynamic (run-time) features versus static (compile-time) features of a language. Although Objective-C and C++ each employ a mix of both features, Objective-C is decidedly geared toward run-time decisions while C++ is geared toward compile-time decisions. The tension between dynamic and static programming involves many of the classic trade-offs in computer science.
-->
==Bibliografia==
|