Objective-C


Objective-C is a high-level general-purpose, object-oriented programming language that adds Smalltalk-style message passing to the C programming language. Originally developed by Brad Cox and Tom Love in the early 1980s, it was selected by NeXT for its NeXTSTEP operating system. Due to Apple macOS’s direct lineage from NeXTSTEP, Objective-C was the standard language used, supported, and promoted by Apple for developing macOS and iOS applications from 1997, when Apple purchased NeXT, until the introduction of the Swift language in 2014.
Objective-C programs developed for non-Apple operating systems or that are not dependent on Apple's APIs may also be compiled for any platform supported by GNU GNU Compiler Collection or LLVM/Clang.
Objective-C source code 'messaging/implementation' program files usually have filename extensions, while Objective-C 'header/interface' files have extensions, the same as C header files. Objective-C++ files are denoted with a filename extension.

History

Objective-C was created mainly by Brad Cox and Tom Love in the early 1980s at their company Productivity Products International (PPI).
Leading up to the creation of their company, both had been introduced to Smalltalk while at ITT Corporation's Programming Technology Center in 1981. The earliest work on Objective-C traces back to around then. Cox was intrigued by problems of true reusability in software design and programming. He realized that a language like Smalltalk would be invaluable in building development environments for system developers at ITT. However, he and Tom Love also recognized that backward compatibility with C was critically important in ITT's telecom engineering milieu.
Cox began writing a pre-processor for C to add some of the abilities of Smalltalk. He soon had a working implementation of an object-oriented extension to the C language, which he named Object-Oriented Pre-Compiler.
Love was hired by Schlumberger Research in 1982 and had the opportunity to acquire the first commercial copy of Smalltalk-80, which further influenced the development of their brainchild. To demonstrate that real progress could be made, Cox showed 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 usable set of libraries, and allow for the code to be bundled into one cross-platform format.
Love and Cox eventually formed PPI to commercialize their product, which coupled an Objective-C compiler with class libraries. In 1986, Cox published the main description of Objective-C in its original form in the book Object-Oriented Programming, An Evolutionary Approach. Although he was careful to explain that there is more to the problem of reusability than just what Objective-C provides, the language was often compared feature for feature with other languages.

Popularization through NeXT

In 1988, NeXT licensed Objective-C from StepStone and extended the GCC compiler to support Objective-C. NeXT developed the Application Kit and Foundation Kit libraries on which the NeXTSTEP user interface and Interface Builder were based. While the NeXT workstations failed to make a great impact in the marketplace, the tools were widely lauded in the industry. NeXT dropped hardware production and focused on software tools, selling NeXTSTEP as a platform for custom programming.
To circumvent the terms of the GPL, NeXT had originally intended to ship the Objective-C frontend separately, allowing the user to link it with GCC to produce the compiler executable. Though initially accepted by Richard M. Stallman, this plan was rejected after Stallman consulted with GNU's lawyers and NeXT agreed to make Objective-C part of GCC.
The work to extend GNU Compiler Collection was led by Steve Naroff, who joined NeXT from StepStone. The compiler changes were made available as per GNU General Public License terms, but the runtime libraries were not, rendering the open source contribution unusable to the general public. This led to other parties developing such runtime libraries under open source licenses. Later, Steve Naroff was also principal contributor to work at Apple to build the Objective-C frontend to Clang.
The GNU project started work on its free software implementation of Cocoa, named GNUstep, based on the OpenStep standard. Dennis Glatting wrote the first GNU Objective-C runtime in 1992. The current GNU Objective-C runtime, in use since 1993, is the one developed by Kresten Krab Thorup while he was a university student in Denmark. Thorup also worked at NeXT from 1993 to 1996.

Apple development and Swift

After acquiring NeXT in 1996, Apple Computer used OpenStep in its then-new operating system, Mac OS X. This included Objective-C, NeXT's Objective-C-based developer tool, Project Builder, and its interface design tool, Interface Builder. Both were later merged into one application, Xcode. Most of Apple's current Cocoa API is based on OpenStep interface objects and is the most significant Objective-C environment being used for active development.
At WWDC 2014, Apple introduced a new language, Swift, which was characterized as "Objective-C without the C".

Syntax

Objective-C is a thin layer atop C and is a "strict superset" of C, meaning that it is possible to compile any C program with an Objective-C compiler and to freely include C language code within an Objective-C class.
Objective-C derives its object syntax from Smalltalk. All of the syntax for non-object-oriented operations are identical to those of C, while the syntax for object-oriented features is an implementation of Smalltalk-style messaging.

Messages

The Objective-C model of object-oriented programming is based on message passing to object instances. In Objective-C, one does not call a method; one sends a message. This is unlike the Simula-style programming model used by C++. The difference between these two concepts is in how the code referenced by the method or message name is executed. In a Simula-style language, the method name is—in most cases—bound to a section of code in the target class by the compiler. In Smalltalk and Objective-C, the target of a message is resolved at runtime, with the receiving object itself interpreting the message. A method is identified by a selector or — a unique identifier for each message name, often just a -terminated string representing its name—and resolved to a C method pointer implementing it: an . A consequence of this is that the message-passing system has no type checking. The object to which the message is directed—the receiver—is not guaranteed to respond to a message, and if it does not, it raises an exception.
Sending the message to the object pointed to by the pointer would require the following code in C++:
obj->method;
In Objective-C, this is written as follows:
;
The "method" call is translated by the compiler to the family of runtime functions. Different implementations handle modern additions like. In GNU families, this function is named, but it has been deprecated in favor of a modern lookup system under.
Both styles of programming have multiple strengths and weaknesses. Object-oriented programming in the Simula style allows multiple inheritance and faster execution by using compile-time binding whenever possible, but it does not support dynamic binding by default. It also forces all methods to have a corresponding implementation unless they are abstract. The Smalltalk-style programming as used in Objective-C allows messages to go unimplemented, with the method resolved to its implementation at runtime. For example, a message may be sent to a collection of objects, to which only some will be expected to respond, without fear of producing runtime errors. Message passing also does not require that an object be defined at compile time. An implementation is still required for the method to be called in the derived object.

Interfaces and implementations

Objective-C requires that the interface and implementation of a class be in separately declared code blocks. By convention, developers place the interface in a header file and the implementation in a code file. The header files, normally suffixed.h, are similar to C header files while the implementation files, normally suffixed.m, can be very similar to C code files.

Interface

This is analogous to class declarations as used in other object-oriented languages, such as C++ or Python.
The interface of a class is usually defined in a header file. A common convention is to name the header file after the name of the class, e.g. would contain the interface for the class.
An interface declaration takes the form:

@interface ClassName : SuperclassName
+ classMethod1;
+ classMethod2;
+ classMethod3:param1_varName;
- instanceMethod1With1Parameter:param1_varName;
- instanceMethod2With2Parameters:param1_varName
param2_callName:param2_varName;
@end

In the above, plus signs denote class methods, or methods that can be called on the class itself, and minus signs denote instance methods, which can only be called on a particular instance of the class. Class methods also have no access to instance variables.
The code above is roughly equivalent to the following C++ interface:

class ClassName : public SuperclassName ;

Note that demonstrates the interleaving of selector segments with argument expressions, for which there is no direct equivalent in C/C++.
Return types can be any standard C type, a pointer to a generic Objective-C object, a pointer to a specific type of object such as NSArray *, NSImage *, or NSString *, or a pointer to the class to which the method belongs. The default return type is the generic Objective-C type.
Method arguments begin with a name labeling the argument that is part of the method name, followed by a colon followed by the expected argument type in parentheses and the argument name. The label can be omitted.

- setRangeStart:start end:end;
- importDocumentWithName:name
withSpecifiedPreferences:prefs
beforePage:insertPage;

A derivative of the interface definition is the category, which allows one to add methods to existing classes.

Implementation

The interface only declares the class interface and not the methods themselves: the actual code is written in the implementation file. Implementation files normally have the file extension .m, which originally signified "messages".

@implementation classname
+ classMethod
- instanceMethod
@end

Methods are written using their interface declarations.
Comparing Objective-C and C:

- method:i


int function

The syntax allows pseudo-naming of arguments.

- changeColorToRed:red green:green blue:blue
// Called like so:
;

Internal representations of a method vary between different implementations of Objective-C. If myColor is of the class, instance method might be internally labeled. The is to refer to an instance method, with the class and then method names appended and colons changed to underscores. As the order of parameters is part of the method name, it cannot be changed to suit coding style or expression as with true named parameters.
However, internal names of the function are rarely used directly. Generally, messages are converted to function calls defined in the Objective-C runtime library. It is not necessarily known at link time which method will be called because the class of the receiver need not be known until runtime.

Instantiation

Once an Objective-C class is written, it can be instantiated. This is done by first allocating an uninitialized instance of the class and then by initializing it. An object is not fully functional until both steps have been completed. These steps should be accomplished with one line of code so that there is never an allocated object that hasn't undergone initialization.
Instantiation with the default, no-parameter initializer:
MyObject *foo = MyObject alloc] init];
Instantiation with a custom initializer:
MyObject *foo = MyObject alloc] initWithString:myString];
In the case where no custom initialization is being performed, the "new" method can often be used in place of the alloc-init messages:
MyObject *foo = ;
Also, some classes implement class method initializers. Like +new, they combine +alloc and -init, but unlike +new, they return an autoreleased instance. Some class method initializers take parameters:

MyObject *foo = ;
MyObject *bar = ;

The alloc message allocates enough memory to hold all the instance variables for an object, sets all the instance variables to zero values, and turns the memory into an instance of the class; at no point during the initialization is the memory an instance of the superclass.
The init message performs the set-up of the instance upon creation. The init method is often written as follows:

- init

In the above example, notice the return type. This type stands for pointer to any object in Objective-C.
The initializer pattern is used to assure that the object is properly initialized by its superclass before the init method performs its initialization. It performs the following actions:
  • Line 2
  • : Sends the superclass instance an message and assigns the result to .
  • Line 3
  • : Checks if the returned object pointer is valid before performing any initialization.
  • Line 6
  • : Returns the value of self to the caller.
A non-valid object pointer has the value ; conditional statements like treat nil like a null pointer, so the initialization code will not be executed if returned nil. If there is an error in initialization, the init method should perform any necessary cleanup, including sending a message to self, and return to indicate that initialization failed. Any checking for such errors must only be performed after having called the superclass initialization to ensure that destroying the object will be done correctly.
If a class has more than one initialization method, only one of them needs to follow this pattern; others should call the designated initializer instead of the superclass initializer.

Protocols

In other programming languages, these are called interfaces.
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 multiple inherited base class in C++, or as an interface. Objective-C makes use of 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 opt to implement. It is specified in the documentation, since it has no presence in the language. Informal protocols are implemented as a category on NSObject and often include optional methods, which, if implemented, can change the behavior of a class. For example, a text field class might have a delegate that implements an informal protocol with an optional method for performing auto-completion of user-typed text. The text field discovers whether the delegate implements that method and, if so, calls the delegate's method to support the auto-complete feature.
A formal protocol is similar to an interface in Java, C#, and Ada 2005. It is a list of methods that any class can declare itself to implement. Objective-C versions before 2.0 required that a class must implement all methods in a protocol it declares itself as adopting; the compiler will emit an error if the class does not implement every method from its declared protocols. Objective-C 2.0 added support for marking certain methods in a protocol optional, and the compiler will not enforce implementation of optional methods.
A class must be declared to implement that protocol to be said to conform to it. This is detectable at runtime. Formal protocols cannot provide any implementations; they simply assure callers that classes that conform to the protocol will provide implementations. In the NeXT/Apple library, protocols are frequently used by the Distributed Objects system to represent the abilities of an object executing on a remote system.
The syntax

@protocol NSLocking
- lock;
- unlock;
@end

denotes that there is the abstract idea of locking. By stating in the class definition that the protocol is implemented,

@interface NSLock : NSObject
//...
@end

instances of NSLock claim that they will provide an implementation for the two instance methods.

Dynamic typing

Objective-C, like Smalltalk, can use dynamic typing: an object can be sent a message that is not specified in its interface. This can allow for increased flexibility, as it allows an object to "capture" a message and send the message to a different object that can respond to the message appropriately, or likewise send the message on to another object. This behavior is known as message forwarding or delegation. Alternatively, an error handler can be used in case the message cannot be forwarded. If an object does not forward a message, respond to it, or handle an error, then the system will generate a runtime exception. If messages are sent to nil, they will be silently ignored or raise a generic exception, depending on compiler options.
Static typing information may also optionally be added to variables. This information is then checked at compile time. In the following four statements, increasingly specific type information is provided. The statements are equivalent at runtime, but the extra information allows the compiler to warn the programmer if the passed argument does not match the type specified.

- setMyValue:foo;

In the above statement, foo may be of any class.

- setMyValue:foo;

In the above statement, foo may be an instance of any class that conforms to the NSCopying protocol.

- setMyValue:foo;

In the above statement, foo must be an instance of the NSNumber class.

- setMyValue:foo;

In the above statement, foo must be an instance of the NSNumber class, and it must conform to the NSCopying protocol.
In Objective-C, all objects are represented as pointers, and static initialization is not allowed. The simplest object is the type that points to, which only has an isa pointer describing its class. Other types from C, like values and structs, are unchanged because they are not part of the object system. This decision differs from the C++ object model, where structs and classes are united.

Forwarding

Objective-C permits the sending of a message to an object that may not respond. Rather than responding or simply dropping the message, an object can forward the message to an object that can respond. Forwarding can be used to simplify implementation of certain design patterns, such as the observer pattern or the proxy pattern.
The Objective-C runtime specifies a pair of methods in
  • forwarding methods:
- forward:sel args:args; // with GCC
- forward:sel args:args; // with NeXT/Apple systems
  • action methods:
- performv:sel args:args; // with GCC
- performv:sel args:args; // with NeXT/Apple systems
An object wishing to implement forwarding needs only to override the forwarding method with a new method to define the forwarding behavior. The action method need not be overridden, as this method merely performs an action based on the selector and arguments. Notice the SEL type, which is the type of messages in Objective-C.
Note: in OpenStep, Cocoa, and GNUstep, the commonly used frameworks of Objective-C, one does not use the class. The method of the class is used to do forwarding.

Example

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

  1. import
@interface Forwarder : Object
// Accessor methods.
- recipient;
- setRecipient:_recipient;
@end

; Forwarder.m

  1. import "Forwarder.h"
@implementation Forwarder
- forward:sel args:args
- setRecipient:_recipient
- recipient
@end

; Recipient.h

  1. import
// A simple Recipient object.
@interface Recipient : Object
- hello;
@end

; Recipient.m

  1. import "Recipient.h"
@implementation Recipient
- hello
@end

; main.m

  1. import "Forwarder.h"
  2. import "Recipient.h"
int main

Categories

During the design of Objective-C, one of the main concerns 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 borrowed and extended the concept of categories from Smalltalk implementations to help with this process.
Furthermore, the methods within a category are added to a class at run-time. Thus, categories permit the programmer to add methods to an existing class – an open class – without the need to recompile that class or even have access to its source code. For example, if a system does not contain a spell checker in its String implementation, it could be added 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.
If a category declares a method 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 name but different method signatures, 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 a step further and allowed for the addition of variables also. Other languages have used prototype-based solutions instead, the most notable being Self.
The C# and Visual Basic (.NET) languages implement superficially similar function in the form of extension methods, but these lack access to the private variables of the class. Ruby and several other dynamic programming languages refer to the technique as "monkey patching".
Logtalk implements a concept of categories that subsumes Objective-C categories function.

Example use of categories

This example builds up an class, by defining first a basic class with only accessor methods implemented, and adding two categories, and, which extend the basic class. While 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. Implementing such accessors is one typical use of categories. Another is to use categories to add methods to the base class. However, it is not regarded as good practice to use categories for subclass overriding, also known as monkey patching. Informal protocols are implemented as a category on the base class. By convention, files containing categories that extend base classes will take the name BaseClass+ExtensionClass.h.
; Integer.h
  1. import
@interface Integer : Object
- integer;
- integer:_integer;
@end

; Integer.m
  1. import "Integer.h"
@implementation Integer
- integer
- integer: _integer
@end

; Integer+Arithmetic.h
  1. import "Integer.h"
@interface Integer
- add: addend;
- sub: subtrahend;
@end

; Integer+Arithmetic.m
  1. import "Integer+Arithmetic.h"
@implementation Integer
- add: addend
- sub: subtrahend
@end

; Integer+Display.h
  1. import "Integer.h"
@interface Integer
- showstars;
- showint;
@end

; Integer+Display.m
  1. import "Integer+Display.h"
@implementation Integer
- showstars
- showint
@end

; main.m
  1. import "Integer.h"
  2. import "Integer+Arithmetic.h"
  3. import "Integer+Display.h"
int main

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.
Class posing was declared deprecated with Mac OS X v10.5, and is unavailable in the 64-bit runtime. Similar function can be achieved by using method swizzling in categories, that swaps one method's implementation with another's that have the same signature.
For the versions still supporting posing, all messages sent to the target class are instead received by the posing class. There are several restrictions:
  • 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.
  • The target class may not have received any messages prior to the posing.
Posing, similarly with categories, allows global augmentation of 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,

@interface CustomNSApplication : NSApplication
@end
@implementation CustomNSApplication
- setMainMenu: menu
@end
class_poseAs ;

This intercepts every invocation of setMainMenu to NSApplication.

#import

In the C language, the #include pre-compile directive always causes a file's contents to be inserted into the source at that point. Objective-C has the #import directive, equivalent except that each file is included only once per compilation unit, obviating the need for include guards.
The Objective-C directive should not be confused with the C++ keyword import, which is used to import C++ modules, and is not a preprocessor directive. It should also not be confused with the #import preprocessor directive in Microsoft Visual C++, which is non-standard and used to import type libraries.

Linux gcc compilation


// FILE: hello.m
  1. import
int main


$ # Compile Command Line for gcc and MinGW Compiler:
$ gcc \
$ \
-o hello \
hello.m \
-L /GNUstep/System/Library/Libraries \
-lobjc \
-lgnustep-base
$./hello

Other features

Objective-C's features often allow for flexible, and often easy, solutions to programming issues.
  • Delegating methods to other objects and remote invocation can be easily implemented using categories and message forwarding.
  • Swizzling of the isa 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 to create database faults. Swizzling is used today by Apple's Foundation Framework to implement Key-Value Observing.

    Major revisions

Objective-C 2.0

At the 2006 Worldwide Developers Conference, Apple announced the release of "Objective-C 2.0," a revision of the Objective-C language to include "modern garbage collection, syntax enhancements, runtime performance improvements, and 64-bit support". Mac OS X v10.5, released in October 2007, included an Objective-C 2.0 compiler. GCC 4.6 supports many new Objective-C features, such as declared and synthesized properties, dot syntax, fast enumeration, optional protocol methods, method/protocol/class attributes, class extensions, and a new GNU Objective-C runtime API.
The naming Objective-C 2.0 represents a break in the versioning system of the language, as the last Objective-C version for NeXT was "objc4". This project name was kept in the last release of legacy Objective-C runtime source code in Mac OS X Leopard.

Garbage collection

Objective-C 2.0 provided an optional conservative, generational garbage collector. When run in backwards-compatible mode, the runtime turned reference counting operations such as "retain" and "release" into no-ops. All objects were subject to garbage collection when garbage collection was enabled. Regular C pointers could be qualified with "__strong" to also trigger the underlying write-barrier compiler intercepts and thus participate in garbage collection. A zero-ing weak subsystem was also provided such that pointers marked as "__weak" are set to zero when the object is collected. The garbage collector does not exist on the iOS implementation of Objective-C 2.0. Garbage collection in Objective-C runs on a low-priority background thread, and can halt on user events, with the intention of keeping the user experience responsive.
Garbage collection was deprecated in Mac OS X v10.8 in favor of Automatic Reference Counting. Objective-C on iOS 7 running on ARM64 uses 19 bits out of a 64-bit word to store the reference count, as a form of tagged pointers.

Properties

Objective-C 2.0 introduces a new syntax to declare instance variables as properties, with optional attributes to configure the generation of accessor methods. Properties are, in a sense, public instance variables; that is, declaring an instance variable as a property provides external classes with access to that property. A property may be declared as "readonly", and may be provided with storage semantics such as assign, copy or retain. By default, properties are considered atomic, which results in a lock preventing multiple threads from accessing them at the same time. A property can be declared as nonatomic, which removes this lock.

@interface Person : NSObject
@property NSString *name;
@property int age;
- initWithAge:age;
@end

Properties are implemented by way of the @synthesize keyword, which generates getter methods according to the property declaration. Alternatively, the getter and setter methods must be implemented explicitly, or the @dynamic keyword can be used to indicate that accessor methods will be provided by other means. When compiled using clang 3.1 or higher, all properties which are not explicitly declared with @dynamic, marked readonly or have complete user-implemented getter and setter will be automatically implicitly @synthesize'd.

@implementation Person
@synthesize name;
- initWithAge:initAge
- age
@end

Properties can be accessed using the traditional message passing syntax, dot notation, or, in Key-Value Coding, by name via the "valueForKey:"/"setValue:forKey:" methods.

Person *aPerson = Person alloc] initWithAge:53];
aPerson.name = @"Steve"; // NOTE: dot notation, uses synthesized setter,
// equivalent to ;
NSLog, dot notation, property name and "
"direct instance variable access ",
,
aPerson.name, , aPerson -> name);

To use dot notation to invoke property accessors within an instance method, the keyword should be used:

- introduceMyselfWithProperties:useGetter

A class or protocol's properties may be dynamically introspected.

int i;
int propertyCount = 0;
objc_property_t *propertyList =
class_copyPropertyList;
for

Non-fragile instance variables

Objective-C 2.0 provides non-fragile instance variables where supported by the runtime. Under the modern runtime, an extra layer of indirection is added to instance variable access, allowing the dynamic linker to adjust instance layout at runtime. This feature allows for two important improvements to Objective-C code:
  • It eliminates the fragile binary interface problem; superclasses can change sizes without affecting binary compatibility.
  • It allows instance variables that provide the backing for properties to be synthesized at runtime without them being declared in the class's interface.

    Fast enumeration

Instead of using an NSEnumerator object or indices to iterate through a collection, Objective-C 2.0 offers the fast enumeration syntax. In Objective-C 2.0, the following loops are functionally equivalent, but have different performance traits.

// Using NSEnumerator
NSEnumerator *enumerator = ;
Person *p;
while


// Using indexes
for


// Using fast enumeration
for

Fast enumeration generates more efficient code than standard enumeration because method calls to enumerate over objects are replaced by pointer arithmetic using the NSFastEnumeration protocol.
NSFastEnumeration is not present on Mac OS X version 10.4 or earlier. Binaries compiled to use this feature will not run on these earlier versions of Mac OS X.

Class extensions

A class extension has the same syntax as a category declaration with no category name, and the methods and properties declared in it are added directly to the main class. It is mostly used as an alternative to a category to add methods to a class without advertising them in the public headers, with the advantage that for class extensions the compiler checks that all the privately declared methods are actually implemented.

Blocks

Blocks is an extension for Objective-C that uses special syntax to create closures. Blocks are only supported in Mac OS X 10.6 "Snow Leopard" or later, iOS 4 or later, and GNUstep with libobjc2 1.7 and compiling with clang 3.1 or later.

  1. include
  2. include
typedef int ;
IntBlock MakeCounter
int main
/* Output:
First call: 5
Second call: 7
Third call: 9
  • /

Modern Objective-C

Apple has added some additional features to Objective 2.0 over time. Apple describe these changes as applying to the "Apple LLVM compiler" only, but they are also found in open-source versions of clang. Confusingly, the versioning used by Apple differs from that of the LLVM upstream; refer to for a translation to open-source LLVM version numbers.

Literals

NeXT and Apple Obj-C runtimes have long included a short-form way to create new strings, using the literal syntax @"a new string", or drop to CoreFoundation constants kCFBooleanTrue and kCFBooleanFalse for NSNumber with Boolean values. Using this format saves the programmer from having to use the longer initWithString: or similar methods when doing certain operations.
When using Apple LLVM compiler 4.0 or later, arrays, dictionaries, and numbers can also be created using literal syntax instead of methods.
Example without literals:

NSArray *myArray = ;
NSDictionary *myDictionary1 = ;
NSDictionary *myDictionary2 = ;
NSNumber *myNumber = ;
NSNumber *mySumNumber= ;
NSNumber *myBoolNumber = ;

Example with literals:

NSArray *myArray = @;
NSDictionary *myDictionary1 = @;
NSDictionary *myDictionary2 = @;
NSNumber *myNumber = @;
NSNumber *mySumNumber = @;
NSNumber *myBoolNumber = @YES;
NSNumber *myIntegerNumber = @8;

In Xcode versions before 13, unlike string literals, array, dictionary, and number literals were compiled into code equivalent to the above method calls. In particular, under manually reference-counted memory management, these objects were autoreleased, which required added care when, for example, used with function-static variables or other kinds of globals.
In Xcode 13 and later, array, dictionary, and number literals can also be embedded into the binary at compile time, just like string literals. This feature is enabled by default on Apple platforms and can be controlled with the -fno-objc-constant-literals and related compiler flags.

Subscripting

When using Apple LLVM compiler 4.0 or later, arrays and dictionaries can be manipulated using subscripting. Subscripting can be used to retrieve values from indexes or keys, and with mutable objects, can also be used to set objects to indexes or keys. In code, subscripting is represented using brackets .
Example without subscripting:

id object1 = ;
id object2 = ;
;
;

Example with subscripting:

id object1 = someArray;
id object2 = someDictionary;
someMutableArray = object3;
someMutableDictionary = object4;

Language variants

Objective-C++

Objective-C++ is a language variant accepted by the front-end to the GNU Compiler Collection and Clang, which can compile source files that use a combination of C++ and Objective-C syntax. The term "Objective-C++" was once featured in the Apple Documentation for their Objective-C compiler as well, but has since been removed.
Objective-C++ adds to C++ the extensions that 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 declarations may appear only in global scope, not inside a C++ namespace.
  • Objective-C classes cannot have instance variables of C++ classes that lack a default constructor or that have one or more virtual methods, but pointers to C++ objects can be used as instance variables without restriction.
  • 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. However, Objective-C types can be used as C++ template parameters.
  • Objective-C and C++ exception handling are distinct; the handlers of each cannot handle exceptions of the other type. As a result, object destructors are not run. This is mitigated in recent "Objective-C 2.0" runtimes as Objective-C exceptions are either replaced by C++ exceptions completely, or partly when Objective-C++ library is linked.
  • Objective-C blocks and C++11 lambdas are distinct entities. However, a block is transparently generated on macOS when passing a lambda where a block is expected.

    "Modern" Objective-C syntax (1997)

After the purchase of NeXT by Apple, attempts were made to make the language more acceptable to programmers more familiar with Java than Smalltalk. One of these attempts was introducing what was termed "Modern Syntax" for Objective-C at the time. There was no change in behaviour, this was merely an alternative syntax. Instead of writing a method invocation like:

object = MyClass alloc] init];
;

It was instead written as

object =.init;
object.labels ;

Similarly, declarations went from the form

- firstLabel: param1 secondLabel: param2;

to

- labels ;

This "modern" syntax is no longer supported in current dialects of the Objective-C language.

Implementations

Objective-C was originally implemented by a proprietary compiler from PPI/StepStone. NeXT instead implemented Objective-C by modifying GCC, allowing newer C features to be used. Apple maintained the situation for a while after its purchase of NeXT, giving rise to Apple GCC and Apple LLVM-GCC, both of which stopped receiving updates at version 4.2.1 due to GCC changing its license to GPLv3, which contains a provision against Tivoization. Apple decided to instead build on top of LLVM's clang compiler since circa 2009, which has a much more relaxed license. Apple contributes Objective-C related changes back to LLVM, making it the most complete open source implementation as of 2026.

GNU, GNUstep, and WinObjC

The GNU project has, for a long time, been interested in a platform to port NeXT and Obj-C programs to. The ChangeLog for the directory in GCC suggests that it existed before 1998, and its README further points at a rewrite in 1993.
The NeXT frontend source code was released since it was made as part of GCC, released GNU General Public License which forces ones making derivative works to do so. Apple continued this tradition in releasing its fork of GCC up to 4.2.1, after which they abandoned the compiler. GCC maintainers took in the changes, but did not invest much in supporting newer features such as the Objective-C 2.0 language.
The GNUstep developers, interested in the new language, forked the GCC to a project independent of GCC called in 2009. They also arranged for the runtime to be used with Clang to take advantage of the new language syntax. GCC moved slowly at the same time, but at GCC 4.6.0 they have moved on to Objective-C 2.0 in their libobjc as well. GNUstep documentation suggest that the GCC implementation still lacks support for blocks, non-fragile variables, and the newer ARC.
Microsoft forked ObjFW's runtime into a part of WinObjC, the iOS bridge for Universal Windows Platform, in 2015, though switched to a fork of in 2016. Combined with its own implementation of Cocoa Touch and underlying APIs, the project allows the reuse of iOS Application code inside of UWP apps.
On Windows, Objective-C Development tools are provided for download on GNUStep's website. The GNUStep Development System consists of the following packages: GNUstep MSYS System, GNUstep Core, GNUstep Devel, GNUstep Cairo, ProjectCenter IDE, Gorm. These binary installers have not been updated since 2016, so it could be a better idea to just install by building under Cygwin or MSYS2 instead.

Clang

The Clang compiler suite, part of the LLVM project, implements Objective-C and other languages. After GCC 4.3 switched to GPLv3, Apple abandoned it in favor of clang, a compiler it has more legal power to modify. As a result, many of the modern Objective-C language features are supported only by Clang.
Apple's versioning scheme for its clang-based "LLVM compiler" differs from the LLVM's open-source versioning. See for a translation.

mulle-objc

The mulle-objc is a performance-oriented implementation of Objective-C. It uses a runtime library written in pure C11, which ensures portability. The runtime library can be statically linked with musl. It uses a fork of clang/LLVM as the compiler and a fork of gdb as the debugger. Mulle-objc has an intentionally reduced feature set, best described as "Objective-C 1.0 with some cherry-picked 2.0 features".

Portable Object Compiler

The Protable Object Compiler was an alternative implementation of Objective-C. The set of extensions implemented by the Portable Object Compiler differs from the GCC/NeXT/Apple implementation; in particular, it includes Smalltalk-like blocks for Objective-C, while it lacks protocols and categories, two features used extensively in OpenStep and its derivatives and relatives. Overall, POC represents an older, pre-NeXT stage in the language's evolution, roughly conformant to Brad Cox's 1991 book.
It also includes a runtime library called ObjectPak, which is based on Cox's original ICPak101 library, and is quite radically different from the OpenStep FoundationKit.

Library use

Objective-C today is often used in tandem with a fixed library of standard objects, such as Cocoa, GNUstep or ObjFW. These libraries often come with the operating system: the GNUstep libraries often come with Linux-based distributions and Cocoa comes with macOS. The programmer is not forced to inherit functions from the existing base class. Objective-C allows for the declaration of new root classes that do not inherit any existing function. 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. 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 that used Object—the original base class used on NeXTSTEP —to co-exist in the same runtime with code that used NSObject. The introduction of the two letter prefix also became a 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.
More recently, package managers have started appearing, such as CocoaPods, which aims to be both a package manager and a repository of packages. A lot of open-source Objective-C code that was written in the last few years can now be installed using CocoaPods.

Analysis of the language

Objective-C implementations use a thin runtime system written in C, which adds little to the size of the application. In contrast, most object-oriented systems at the time that it was created used large virtual machine runtimes. Programs written in Objective-C tend to be not much larger than the size of their code and that of the libraries, in contrast to Smalltalk systems where a large amount of memory was used just to open a window. Objective-C applications tend to be larger than similar C or C++ applications because Objective-C [|dynamic typing] does not allow methods to be stripped or inlined. Since the programmer has such freedom to delegate, forward calls, build selectors on the fly, and pass them to the runtime system, the Objective-C compiler cannot assume it is safe to remove unused methods or to inline calls.
Likewise, the language can be implemented atop extant C compilers rather than as a new compiler. This allows Objective-C to leverage the huge existing collection of C code, libraries, tools, etc. Existing C libraries can be wrapped in Objective-C wrappers to provide an OO-style interface. In this aspect, it is similar to GObject library and Vala language, which are widely used in development of GTK applications.
All of these practical changes lowered the barrier to entry, likely the biggest problem for the widespread acceptance of Smalltalk in the 1980s.
A common criticism is that Objective-C does not have language support for namespaces. Instead, programmers are forced to add prefixes to their class names, which are traditionally shorter than namespace names and thus more prone to collisions. As of 2007, all macOS classes and functions in the Cocoa programming environment are prefixed with "NS" to identify them as belonging to the macOS or iOS 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.
Unlike C++, Objective-C does not support operator overloading. Also unlike C++, Objective-C allows an object to directly inherit from only one class. However, in most cases, categories and protocols may be used as alternative ways to achieve the same results.
Because Objective-C uses dynamic runtime typing and because all method calls are function calls, many common performance optimizations cannot be applied to Objective-C methods. This limits the performance of Objective-C abstractions relative to similar abstractions in languages such as C++ where such optimizations are possible.

Memory management

The first versions of Objective-C did not support garbage collection. At the time this decision was a matter of some debate, and many people considered long "dead times" to render the entire system unusable. Some 3rd party implementations have added this feature, and Apple has implemented it as of Mac OS X v10.5. However, in more recent versions of macOS and iOS, garbage collection has been deprecated in favor of Automatic Reference Counting, introduced in 2011.
With ARC, the compiler inserts retain and release calls automatically into Objective-C code based on static code analysis. The automation relieves the programmer of having to write in memory management code. ARC also adds weak references to the Objective-C language.

Philosophical differences between Objective-C and C++

The design and implementation of C++ and Objective-C represent fundamentally different approaches to extending C.
In addition to C's style of procedural programming, C++ directly supports certain forms of object-oriented programming, generic programming, and metaprogramming. C++ also comes with a large standard library that includes several container classes. Similarly, Objective-C adds object-oriented programming, dynamic typing, and reflection to C. Objective-C does not provide a standard library per se, but in most places where Objective-C is used, it is used with an OpenStep-like library such as OPENSTEP, Cocoa, or GNUstep, which provides functions similar to C++'s standard library.
One notable difference is that Objective-C provides runtime support for reflective programming 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, e.g., whether it will respond to a certain message. In C++, this is not possible without the use of external libraries.
The use of reflection is part of the wider distinction between dynamic features and static features of a language. Although Objective-C and C++ each employ a mix of both features, Objective-C favors run-time decisions while C++ favors compile-time decisions. The tension between dynamic and static programming involves many of the classic trade-offs in programming: dynamic features add flexibility, static features add speed and type checking.
Generic programming and metaprogramming can be implemented in both languages using runtime polymorphism. In C++, this takes the form of virtual functions and runtime type identification, while Objective-C offers dynamic typing and reflection. Both Objective-C and C++ support compile-time polymorphism, with Objective-C adding this feature in 2015.

Similarly-named languages

GEOS Objective-C

The PC GEOS system used a programming language known as GEOS Objective-C or goc; despite the name similarity, the two languages are similar only in overall concept and the use of keywords prefixed with an @ sign.