All writing

Objective-C Categories and Class Extensions

Extending classes at runtime and compile time

Categories

What is a category?

A category extends the behavior of an existing class. It is especially useful when the class's source code is unavailable—for example, when adding convenience methods to framework types such as NSString, UIButton, or UILabel.

Objective-C's dynamic runtime lets a category add methods without creating a subclass. This is often a smaller and more composable alternative to inheritance, and it works with classes from Foundation, UIKit, and other frameworks whose implementations you do not control.

Creating a category

The category template in Xcode 10 can be created and configured as follows:

Creating a category in Xcode

Configuring a category in Xcode

Common uses

  • Add focused behavior to a system framework class that cannot be edited directly.
  • Organize a large class into feature-oriented implementation files.
  • Declare methods that are implemented elsewhere so the compiler knows about them. This can expose otherwise undeclared methods to a specific compilation unit, although it does not create true privacy boundaries.

For example:

// A.m
- (void)test {
    // A simple implementation for demonstration.
    // NSLog(@"test");
}

// A+CategoryA.h
- (void)test;

Limitations

A category can add methods, but it cannot add storage to the original instance layout. That layout was fixed when the class was compiled. A property declared in a category therefore does not automatically receive a backing ivar or synthesized accessors.

Associated objects provide a runtime-based alternative. objc_setAssociatedObject attaches a value to an existing object by key, and objc_getAssociatedObject retrieves it later. When a category declares a property backed by associated storage, it must implement the getter and setter explicitly.

Using associated objects from a category

The main parameters are:

  1. The source object.
  2. A unique key identifying the associated value.
  3. The value being associated.
  4. The association policy, which defines memory-management and atomicity behavior.

If a category and its original class implement the same selector, the category implementation can replace the class's implementation at runtime. When multiple categories provide the same selector, load order determines the winner and should not be treated as a reliable design contract. In practice, categories should avoid selector collisions.

Class Extensions

What is a class extension?

A class extension uses category-like syntax without a category name, which is why it is sometimes called an anonymous category. It is primarily used to declare private methods, properties, and ivars that belong to a class's own implementation.

Unlike a category, an extension is part of the class at compile time. Its declared members are expected to be implemented by the class, and the compiler can diagnose missing implementations.

Ways to use an extension

A separate private header

An extension can live in a separate header shared by selected implementation files. This helps organize internal APIs, but it does not make them truly private: any source file importing that header can see the declarations.

An extension in the implementation file

The most common approach is to declare the extension directly inside the class's .m file. Other files normally import headers rather than implementation files, so this keeps internal properties and methods out of the public interface.

Objective-C does not provide an absolute runtime privacy boundary, but this structure gives the compiler and other developers a clear API boundary.

Methods declared only in @implementation

A method may also be implemented directly inside @implementation without appearing in the public interface. This can hide a small helper, although a class extension is usually clearer when several private members belong together.

A note on inheritance

Subclassing is another way to add behavior, but it creates a stronger relationship and can make a design harder to understand when the inheritance hierarchy becomes deep. Categories and extensions are useful when the goal is organization or focused behavior rather than polymorphism.

Category vs. Extension

Practical differences

  1. A class extension is anonymous; a category has a name.
  2. Extension declarations are checked as part of the class implementation. Category methods are not required to be implemented.
  3. An extension can introduce properties and ivars because it participates in class compilation. A category cannot change the compiled instance layout and needs associated objects for additional storage.

Although class extensions are often described as anonymous categories, their lifecycle and implementation model are substantially different.

How extensions are applied

  1. The compiler resolves an extension together with the class interface and implementation.
  2. Its members are created and destroyed with the class itself.
  3. Adding an extension requires access to the class's source implementation, so framework classes such as NSString cannot be extended this way.

How categories are applied

  1. Categories are attached by the Objective-C runtime.
  2. They cannot normally add ivars because the object's memory layout has already been established.
  3. Changing that layout after compilation would invalidate assumptions made by existing compiled code.