What is Objective-C? History, Influences, and the Language Today

Explain what Objective-C actually is — a strict superset of C with an object-messaging system layered on top — trace its history from Smalltalk and NeXT through Apple's acquisition to modern Objective-C, and clearly separate the language itself from the Foundation/Cocoa frameworks built on top of it.

Everything you learned in the previous module — variables, types, constants, functions, pointers, the whole preprocess/compile/link pipeline driven by clang — was C, and none of it goes away now. Objective-C does not replace C or hide it; it adds to it. This lesson is the bridge between the two halves of this course: it explains, at a conceptual level, exactly what gets added on top of C to make it Objective-C, where that addition came from historically, and how the language has evolved since. Understanding this history is not just trivia — it explains why Objective-C's syntax looks the way it does (why messages are sent in square brackets instead of called with parentheses like a normal C function), why the language feels like two different worlds stitched together (because it literally is), and why so much of what you'll actually write day to day lives in a framework called Foundation rather than in the language's core syntax at all.

Objective-C is a Strict Superset of C

The single most important fact about Objective-C, and the one this entire course has been building toward, is this: Objective-C is a strict superset of C. That means every valid C program — every for loop, every struct, every pointer, every function you wrote in the previous module — is also a valid Objective-C program, unchanged, compiling and running exactly the same way. Objective-C does not redefine or remove any part of C; it purely adds new syntax on top, specifically syntax for sending messages to objects. A .m file can be 100% plain C with zero object-oriented syntax anywhere in it, and it is still, technically and practically, an Objective-C file — the compiler simply never encounters any of the new syntax and treats it exactly as it would a .c file.

This 'superset' relationship is different from how many other object-oriented languages relate to their procedural ancestors. C++ also extends C, but it changed and restricted parts of C's grammar and type system along the way (some valid C is not valid C++). Objective-C took the opposite, more conservative path: it left C's grammar completely untouched and bolted on an entirely separate, visually distinct syntax for its object system — square-bracket message sends — specifically so the two could coexist in the same file without any ambiguity about which language a given line of code belongs to. When the compiler sees [receiver message], it knows immediately it's looking at an Objective-C message send; when it sees printf("hello");, it knows it's looking at a plain C function call. There is never any confusion between the two, because they simply look different.

Practically, this means you can write an entire Objective-C program using only object-oriented style, only C style, or — as most real-world Objective-C code actually does — a deliberate mixture of both: C for low-level numeric work, loops, and structs, and Objective-C's object system for anything modeling a 'thing' with behavior and state, like a user, a network request, or a view on screen. Nothing in this course's earlier C material was a detour; it was literally half of the language you are now learning to use.

• Objective-C is a strict superset of C: every valid C program is also valid Objective-C, unchanged. • Objective-C leaves C's grammar completely untouched and adds a visually separate syntax (square brackets) for its object system. • This differs from C++, which modified parts of C's own grammar and type rules while extending it. • Real Objective-C code freely mixes plain C (loops, structs, arithmetic) with object-messaging syntax in the same file, even the same function.

The Smalltalk Influence: Where '[receiver message]' Comes From

If Objective-C's object syntax isn't inherited from C, where did it come from? The answer is Smalltalk, a pioneering object-oriented programming language and environment developed at Xerox PARC in the 1970s, largely credited with originating the term 'object-oriented programming' itself along with many of its now-standard ideas: objects that bundle data and behavior together, classes as templates for creating objects, and — most relevant here — the idea that you don't 'call a method on' an object the way you call a function; you send that object a message, and the object itself decides, at the moment it receives that message, how to respond.

That message-sending idea is precisely what Objective-C's [receiver message] syntax expresses, almost letter for letter translated from Smalltalk's own notation. When you write [account deposit:100], you are not (conceptually) directly invoking a specific block of code the way a C function call deposit(account, 100) would; you are sending the message deposit:100 to the object account, and it is up to that object — at runtime, based on its actual class — to decide what code actually runs in response. This might sound like a distinction without a difference for now, but it has real consequences you'll explore in depth in later modules: because the connection between a message and the code that handles it is resolved dynamically, at runtime, rather than fixed permanently at compile time, Objective-C supports patterns like an object simply not responding to a message it doesn't understand (with a well-defined error), one object dynamically forwarding messages it receives on to a completely different object, and swapping out what a message actually does while the program is already running. None of that would be possible if [receiver message] were merely disguised syntax for an ordinary, statically-resolved C function call.

It's worth being precise about what Objective-C did and didn't take from Smalltalk. It took the message-sending object model and its bracket-based syntax almost directly. It did not take Smalltalk's live, image-based development environment, nor did it adopt Smalltalk's own syntax wholesale — Objective-C's class and method declaration syntax (which you'll see starting in the next module) is its own design, distinct from Smalltalk's. Brad Cox, credited as Objective-C's principal designer, was explicit about the goal: bring Smalltalk's dynamic message-passing object model to the practical, high-performance, close-to-the-hardware world of C, rather than trying to recreate Smalltalk's entire environment from scratch.

• Smalltalk (Xerox PARC, 1970s) pioneered object-oriented ideas: objects bundling data and behavior, classes, and — crucially — message sending rather than direct function calls. • Objective-C's [receiver message] syntax is a direct descendant of Smalltalk's own message-passing notation. • 'Sending a message' is conceptually different from 'calling a function': the object itself decides at runtime how to respond, enabling dynamic patterns explored later in the course. • Objective-C borrowed Smalltalk's message-passing object model, not its full development environment or its concrete syntax elsewhere in the language.

From NeXTSTEP to Apple: The History of Objective-C

Objective-C was created in the early 1980s by Brad Cox and Tom Love, working at their company Stepstone (originally named Productivity Products International). Cox, who had prior exposure to Smalltalk's ideas, wanted a language that combined Smalltalk-style object messaging with C's practicality, performance, and enormous existing base of tools and code — rather than asking developers to abandon C entirely, Objective-C let them keep everything they already had and simply add object-oriented capability where it was useful. Stepstone initially implemented Objective-C as a preprocessor that translated Objective-C source into plain C, which a standard C compiler could then build — an early, concrete demonstration of the 'superset of C' idea baked into the language's implementation itself.

The turning point for Objective-C's future came when Steve Jobs's company NeXT, founded after Jobs left Apple in 1985, licensed Objective-C from Stepstone to build NeXTSTEP, an advanced object-oriented operating system and development environment for NeXT's workstation computers. NeXT built an entire application framework on top of Objective-C, providing reusable objects for windows, menus, text views, and the like — this framework was the direct ancestor of what is now called Cocoa. NeXT's engineers (and Cox's earlier work) also gave the language its two core standard library building blocks that survive to this day almost unchanged in name: the Foundation framework (basic, non-UI utility objects — strings, collections, dates) and AppKit (the UI framework for building application windows and controls).

NeXTSTEP itself was a commercial underdog through the late 1980s and 1990s — technically admired, commercially modest — but its story took a dramatic turn in December 1996, when Apple, searching for a modern operating system foundation to replace its aging classic Mac OS, acquired NeXT for roughly 400 million dollars, bringing Objective-C, NeXTSTEP's object model, and (not incidentally) Steve Jobs himself back into Apple. NeXTSTEP became the technical foundation of what Apple would eventually ship as Mac OS X (first released 2001), with NeXTSTEP's AppKit evolving into Mac OS X's Cocoa, and Objective-C becoming Apple's primary application-development language for the next roughly fifteen years, later extending to iOS when the iPhone launched in 2007 and needed its own object-oriented application framework, UIKit, built on the very same Objective-C and Foundation foundations.

• Objective-C was created in the early 1980s by Brad Cox and Tom Love at Stepstone, initially implemented as a preprocessor translating to plain C. • NeXT (Steve Jobs's post-Apple company) licensed Objective-C to build NeXTSTEP, whose application framework was the direct ancestor of Cocoa. • Apple acquired NeXT in December 1996, bringing Objective-C and NeXTSTEP's technology back into Apple as the foundation for Mac OS X. • NeXTSTEP's AppKit became Mac OS X's Cocoa; the same lineage later produced UIKit for iOS (2007), all built on Objective-C and Foundation.

The Objective-C Runtime: Where the Dynamism Lives

A key architectural fact that separates Objective-C from many other compiled object-oriented languages is where its object-oriented behavior actually lives: not entirely in the compiler, but substantially in a separate piece of software called the Objective-C runtime — a C library, linked into every Objective-C program, that manages the low-level mechanics of objects and message sending while the program is actually executing. When the compiler encounters [account deposit:100], it does not, in general, hard-wire that call to one specific block of machine code the way a plain C function call is resolved; instead it typically generates a call into the runtime function objc_msgSend, passing along the receiver (account), the message being sent (deposit:), and the arguments (100). It is the runtime, executing at that exact moment, that looks up account's actual class, finds the right method implementation for that message, and invokes it.

This runtime-mediated design is precisely what gives Objective-C its dynamic character, distinguishing it from more rigidly statically-bound object-oriented languages. Because message dispatch happens through the runtime at the moment a message is sent, rather than being permanently fixed at compile time, Objective-C supports capabilities that will be explored in depth in a dedicated later module: introspection (an object can be asked, while the program is running, what class it belongs to or whether it responds to a particular message), dynamic method resolution, and message forwarding (redirecting a message an object doesn't itself handle to some other object entirely). None of this requires any special compiler magic each time — it's simply how the runtime always works, for every single message send in every Objective-C program.

For now, the important mental model is simply this: Objective-C is really two cooperating pieces working together — a compiler (clang) that understands Objective-C's syntax and translates it into calls into the runtime, and a runtime library (libobjc) that actually carries out object creation, message dispatch, and memory bookkeeping while the program executes. Later modules will open this up in real detail; for now, just remember that when you see [receiver message], there is a real, separate piece of software — the runtime — doing genuine work behind that syntax every single time it executes, not just a disguised function call resolved once and for all at compile time.

• The Objective-C runtime (libobjc) is a separate C library, linked into every program, that manages objects and message dispatch at execution time. • [receiver message] typically compiles down to a call into the runtime function objc_msgSend, which looks up and invokes the right code at that moment. • Because dispatch happens through the runtime rather than being fixed permanently at compile time, Objective-C supports introspection, dynamic resolution, and message forwarding. • Two cooperating pieces make up the language in practice: the clang compiler (translates syntax) and the runtime library (executes object behavior).

Objective-C 2.0 and the Modern Language

The Objective-C used in the earliest NeXTSTEP and Mac OS X years stayed relatively stable for roughly two decades, but Apple made a significant round of language additions in 2006, formally called Objective-C 2.0, introduced alongside Mac OS X 10.5 'Leopard'. Objective-C 2.0 added properties — a declarative way to expose an object's data with automatically generated accessor methods, replacing a great deal of repetitive hand-written getter/setter boilerplate — and fast enumeration, a cleaner for...in style loop syntax for iterating over collections, replacing older, more verbose iteration patterns. Objective-C 2.0 also introduced an optional garbage collector for Mac OS X (not iOS), intended to relieve developers of manually tracking object lifetimes; this particular feature did not stand the test of time well — it was deprecated a few years later and never adopted on iOS at all, ultimately being fully removed from the language, but properties and fast enumeration became permanent, foundational parts of how Objective-C code is written from that point forward.

The far more consequential and lasting shift in Objective-C's memory management story arrived in 2011, when Apple introduced Automatic Reference Counting (ARC). Where earlier Objective-C required developers to manually balance calls that incremented and decremented an object's reference count (a pattern called manual retain-release, MRR, which you'll study in this course's dedicated Memory Management module), ARC moved that bookkeeping into the compiler itself: at compile time, clang analyzes your code and automatically inserts the correct retain and release calls for you, eliminating an entire, historically very common category of memory bugs (leaks from forgetting to release, and crashes from releasing too early) without the runtime overhead of a full garbage collector. ARC has been the default, expected memory-management approach for all new Objective-C code since its introduction, and this course teaches ARC as the standard, covering manual reference counting separately, later, mainly so you can read and understand older existing code.

Further refinements followed through the 2010s: 2012 brought Objective-C literals and subscripting syntax — concise notation like @[obj1, obj2] for creating an NSArray, @{key: value} for an NSDictionary, @42 for wrapping a plain number in an NSNumber object, and array[0] / dictionary[key] subscript syntax for accessing elements — all replacing longer, more verbose method-call-based ways of doing the exact same things. 2015 added nullability annotations (nullable / nonnull, letting you declare in a header whether a pointer is allowed to be nil, which the compiler can then check) and lightweight generics for collection classes (letting you write NSArray<NSString *> * to declare 'an array specifically of strings', improving compile-time type checking for collections that were previously untyped). None of these later additions changed Objective-C's fundamental object model or its Smalltalk-derived message-passing core — they are all, in different ways, syntactic conveniences and safety improvements layered on top of the same foundation established by the original language design and cemented by Objective-C 2.0.

• Objective-C 2.0 (2006, alongside Mac OS X Leopard) added properties, fast enumeration (for...in), and an optional (later removed) garbage collector. • Automatic Reference Counting (ARC, 2011) moved manual retain/release memory bookkeeping into the compiler itself, becoming the modern default. • 2012: literals and subscripting syntax (@[...], @{...}, @42, array[0]) as concise replacements for longer method-call equivalents. • 2015: nullability annotations (nullable/nonnull) and lightweight generics for collections (NSArray<NSString *> *), improving compiler-checked safety. • None of these additions changed the underlying Smalltalk-derived message-passing object model — they are conveniences and safety layered on top of it.

The Language vs. the Frameworks: Objective-C, Foundation, and Cocoa

One of the most important conceptual distinctions to establish early, and one beginners frequently blur, is the difference between Objective-C the language and Foundation/Cocoa the frameworks built with it. Objective-C itself is quite a small language: its core additions on top of C amount to class and method declaration syntax, the message-sending [receiver message] syntax, a handful of @-prefixed keywords (@interface, @implementation, @property, @autoreleasepool, and a few others you'll meet across this course), and the runtime that supports all of it. The language on its own does not give you strings, arrays, dictionaries, or any of the rich data types you'd expect to use constantly — those all come from Foundation, a separate framework (a pre-built library of classes) that happens to be written in Objective-C and is almost universally used alongside it, but is conceptually and technically distinct from the language itself.

This is directly analogous to a distinction you already understand from the C portion of this course: printf is not part of the C language's grammar — it's a function provided by the C standard library, which you access via #include <stdio.h>. Similarly, NSString, NSArray, NSDictionary, and virtually every other class whose name starts with the NS prefix (a historical holdover from NeXTSTEP) are not part of Objective-C the language — they are classes provided by the Foundation framework, which you access via #import <Foundation/Foundation.h>, exactly as you'll see in the very next lesson. You could, in principle, write Objective-C code that never imports Foundation and never uses a single NS-prefixed class, defining every one of your own classes and using only plain C data underneath — it would be valid, if unusually spartan, Objective-C.

Cocoa (for Mac apps) and Cocoa Touch / UIKit (for iOS apps) sit one further layer up: they are larger, more specialized framework collections, themselves built using Objective-C and depending on Foundation, that add UI-specific and platform-specific classes on top — windows, buttons, view controllers, touch handling. So the layering, bottom to top, is: C (the base language) → Objective-C (C plus the object-messaging system and its runtime) → Foundation (general-purpose objects: strings, collections, dates, networking primitives) → Cocoa/UIKit (platform-specific UI and application-architecture classes). Keeping this layering straight — which of these four you're actually working with at any given moment — will make the rest of this course, and any Objective-C code you read outside it, dramatically easier to reason about.

• Objective-C the language is small: class/method syntax, message sending, a handful of @-keywords, and the runtime — that's essentially it. • Foundation is a separate framework (not part of the language) providing NSString, NSArray, NSDictionary, and most everyday data types. • Analogy: printf is to the C standard library as NSString is to Foundation — neither is part of the core language grammar. • Cocoa (Mac) and Cocoa Touch/UIKit (iOS) are further, higher framework layers on top of Foundation, adding UI and application-architecture classes. • Layering: C → Objective-C (language + runtime) → Foundation (general-purpose objects) → Cocoa/UIKit (platform UI frameworks).

Code Examples

The C version calls addNumbers directly -- the compiler links this call to one specific function, fixed permanently at compile/link time, exactly as covered in the previous module. The Objective-C version sends the message addNumber:toNumber: to the object calculator -- the actual code that runs is determined by the Objective-C runtime at the moment the message is sent, based on calculator's actual class, which is the core distinction this lesson introduces.

This one file freely mixes both halves of the language: squareOf is a completely plain C function, called the ordinary C way. @(value) and NSLog are Objective-C, working with an actual NSNumber object. This is exactly what it means for Objective-C to be a strict superset of C -- both styles coexist in the same file, even the same function, with no conflict. Expected result: Squared value: 36

// Plain C: a function call, resolved directly to one block of code
int total = addNumbers(3, 4);

// Objective-C: a message send, resolved by the runtime at execution time
NSNumber *total = [calculator addNumber:@3 toNumber:@4];
#import <Foundation/Foundation.h>

int squareOf(int n) {          // plain C function -- entirely valid here
    return n * n;
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        int value = squareOf(6);              // ordinary C function call
        NSNumber *boxed = @(value);             // Objective-C object literal
        NSLog(@"Squared value: %@", boxed);     // Objective-C message-based logging
    }
    return 0;
}

How Objective-C is Assembled

Objective-C is built by fusing C (syntax, performance, low-level control) with Smalltalk's message-passing object model, mediated at execution time by the Objective-C runtime. Foundation and Cocoa are frameworks built on top, not part of the language itself.

// Believing NSString, NSArray, etc. are part of the Objective-C language itself, // and that any .m file automatically has access to them with no #import at all.

NS-prefixed classes come from the Foundation framework, not from the Objective-C language core. Without importing Foundation's header, the compiler has no idea what NSString or NSLog even are, exactly as printf is unavailable without #include <stdio.h> in plain C.

// Assuming [receiver message] is just C function-call syntax with different punctuation, // resolved once and for all at compile time the same way addNumbers(3,4) is.

// Understanding that a message send is dispatched by the Objective-C runtime // at the moment the message is actually sent, based on the receiver's real class.

Message sends are runtime-mediated, not statically resolved the way ordinary C function calls are. This distinction is what later enables dynamic behavior like introspection and message forwarding, covered in depth in a later module -- treating it as 'just a function call with brackets' will cause confusion once that material arrives.

// Thinking Objective-C invented the message-passing object model from scratch.

// Objective-C's [receiver message] syntax is a direct descendant of Smalltalk's // message-passing notation, adapted onto a C foundation by Brad Cox and Tom Love.

Objective-C's core object-messaging idea traces directly to Smalltalk, developed years earlier at Xerox PARC. Knowing this lineage explains why the syntax looks so different from C's own function-call syntax -- it comes from an entirely separate language tradition, deliberately fused onto C.

What does it mean that Objective-C is a 'strict superset of C'? A. Objective-C removed several C features to simplify the language B. Every valid C program is also a valid Objective-C program, unchanged; Objective-C only adds new syntax on top C. Objective-C and C share no code or syntax in common D. Objective-C programs must avoid using any C syntax at all

B. Every valid C program is also a valid Objective-C program, unchanged; Objective-C only adds new syntax on top — A strict superset means C's grammar is fully preserved and untouched; Objective-C purely adds new syntax (message sending, class declarations) on top, so any valid C file is automatically also valid Objective-C.

Where did Objective-C's [receiver message] syntax and its underlying object model come from? A. It was invented independently by Apple in 2007 for the iPhone B. It was adapted from Smalltalk's message-passing object model, developed earlier at Xerox PARC C. It was copied directly from C++'s method-call syntax D. It originated in the C standard library

B. It was adapted from Smalltalk's message-passing object model, developed earlier at Xerox PARC — Brad Cox and Tom Love designed Objective-C's message-sending syntax and object model as an adaptation of ideas from Smalltalk, a pioneering object-oriented language from Xerox PARC in the 1970s, fused onto a C foundation.

Which historical event brought Objective-C and NeXTSTEP's technology into Apple, eventually forming the basis of Mac OS X? A. Apple's founding in 1976 B. The release of the first iPhone in 2007 C. Apple's acquisition of NeXT in December 1996 D. The introduction of Objective-C 2.0 in 2006

C. Apple's acquisition of NeXT in December 1996 — Apple acquired Steve Jobs's company NeXT in December 1996, bringing NeXTSTEP -- and with it Objective-C and its object model -- into Apple, where it became the technical foundation of Mac OS X and, later, iOS.

What is the correct relationship between Objective-C the language and Foundation the framework? A. They are the same thing; Foundation classes are part of the language's core grammar B. Foundation is a separate library of classes (NSString, NSArray, etc.) written in Objective-C and used alongside it, but distinct from the language itself C. Foundation is an older, deprecated version of Objective-C D. Objective-C cannot be used without Foundation under any circumstances

B. Foundation is a separate library of classes (NSString, NSArray, etc.) written in Objective-C and used alongside it, but distinct from the language itself — Objective-C the language is small -- class/method syntax, message sending, a few @-keywords, and the runtime. NSString, NSArray, and similar classes come from Foundation, a separate framework, analogous to how printf comes from the C standard library rather than C's core grammar.

What major capability did Automatic Reference Counting (ARC), introduced in 2011, move into the compiler? A. Message dispatch through the Objective-C runtime B. Class and method declaration parsing C. The bookkeeping of retaining and releasing objects for memory management, previously done manually D. The translation of #import directives

C. The bookkeeping of retaining and releasing objects for memory management, previously done manually — ARC had clang automatically insert the correct retain and release calls at compile time, replacing the older manual retain-release (MRR) approach where developers balanced those calls by hand, eliminating a large class of memory bugs.

Objective-C
                     │
          ┌──────────┴──────────┐
          ↓                     ↓
          C                Smalltalk ideas
          │                     │
          └──────────┬──────────┘
                     ↓
              Objective-C Runtime
                     ↓
          Foundation / Cocoa APIs