100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Categories and Extensions

How Objective-C categories add methods to existing classes without subclassing, and how class extensions expose private, writable state.

OOP in Objective-CIntermediate9 min readJul 10, 2026
Analogies

Categories and Extensions

A category lets a developer add new methods to an existing class, even one they don't own the source code for, such as NSString or NSArray, without subclassing it, by declaring @interface ClassName (CategoryName) ... @end and providing matching method bodies in a similarly named @implementation. Every instance of that class, existing ones and future ones alike, gains the new methods immediately, because a category literally extends the class's method table at runtime rather than creating a separate subclass.

🏏

Cricket analogy: Like a groundskeeper adding a new drainage system to an existing historic stadium like Lord's without demolishing and rebuilding it, a category adds new methods to an existing class without subclassing or rewriting it.

Category Syntax and Limitations

A category is named in parentheses after the class it extends, for example @interface NSString (Reversing) declares a category called Reversing on NSString, and its implementation adds a method like - (NSString *)reversedString that becomes callable on any NSString instance anywhere in the app once the category's file is compiled in. The critical limitation is that a category cannot declare new instance variables or new @property-backed storage (though it can declare a @property whose accessors you implement manually, backed by associated objects via objc_setAssociatedObject), and if a category redefines a method that already exists on the class, which method wins at runtime is undefined and depends on link order, so category method names should be distinctive to avoid silent collisions.

🏏

Cricket analogy: Like adding a new fielding restriction rule to T20 cricket that changes how the game is played (a new method) without being able to add a whole new type of pitch to every ground overnight (no new storage), a category adds behavior but not new stored state.

Class Extensions: Anonymous Categories for Private API

A class extension is a special category with no name, written as @interface ClassName () ... @end, typically placed at the top of the .m implementation file rather than in the public .h header, and unlike a named category, a class extension can declare additional instance variables and readwrite properties that redeclare a readonly property from the public header as writable internally. This is the standard pattern for exposing a readonly property publicly (so external code can only read it) while allowing the class's own methods to freely mutate it privately, by redeclaring it as readwrite inside the class extension.

🏏

Cricket analogy: Like a franchise's public roster sheet showing a player's stats as fixed for fans (readonly) while the team's internal analytics department can freely update those same numbers behind the scenes (readwrite), a class extension exposes private mutability behind a public readonly facade.

objectivec
// NSString+Reversing.h  (a named category)
@interface NSString (Reversing)
- (NSString *)reversedString;
@end

// NSString+Reversing.m
@implementation NSString (Reversing)
- (NSString *)reversedString {
    NSMutableString *reversed = [NSMutableString stringWithCapacity:self.length];
    for (NSInteger i = self.length - 1; i >= 0; i--) {
        [reversed appendFormat:@"%C", [self characterAtIndex:i]];
    }
    return reversed;
}
@end

// usage anywhere in the app, no subclassing needed
NSString *word = @"Objective-C";
NSLog(@"%@", [word reversedString]); // "C-evitcejbO"

// --- Class extension example (in Account.m) ---
// Account.h declares: @property (nonatomic, assign, readonly) double balance;

@interface Account ()
@property (nonatomic, assign, readwrite) double balance; // internally mutable
@end

@implementation Account
- (void)depositAmount:(double)amount {
    self.balance += amount; // allowed here, blocked for external callers
}
@end

Adding a category to a Foundation class like NSString is a common and safe pattern for utility methods, but adding categories to classes you don't control, especially UIKit classes, requires distinctive, prefixed method names (like sv_reversedString instead of reversedString) to avoid silently colliding with a method Apple might add in a future SDK release.

If two categories on the same class both implement a method with the identical name, only one implementation wins at runtime and which one is undefined, determined by link order, not declaration order in your project. This kind of silent category collision is notoriously hard to debug because there's no compiler error, just unexpected behavior at a specific call site.

  • A category adds new methods to an existing class, even ones you don't own, without subclassing it.
  • Category syntax is @interface ClassName (CategoryName) ... @end plus a matching @implementation.
  • Categories cannot add new instance variables or new @property-backed storage.
  • Colliding category method names on the same class produce undefined behavior at runtime, based on link order.
  • A class extension is an unnamed category, @interface ClassName () ... @end, usually placed in the .m file.
  • Unlike named categories, class extensions can add ivars and can redeclare a property as readwrite privately.
  • The public-readonly, private-readwrite pattern via a class extension is the standard way to expose safe, one-directional access.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#ObjectiveCStudyNotes#CategoriesAndExtensions#Categories#Extensions#Category#Syntax#StudyNotes#SkillVeris#ExamPrep