The + and - prefixes
In an Objective-C @interface, a method prefixed with - is an instance method, callable only on a specific object instance and operating on that instance's own state via self and its ivars, while a method prefixed with + is a class method, callable directly on the class itself (e.g., [NSString stringWithFormat:...]) without needing any instance to already exist. Class methods are conceptually similar to static methods in Java or C++, but because Objective-C classes are themselves objects (of a metaclass), class methods are dispatched dynamically too, and can even be overridden by subclasses.
Cricket analogy: A class method is like calling the ICC rulebook directly ('what's the over limit for a T20 match?') without needing any specific match to be underway, while an instance method is like asking a specific ongoing match 'what's your current score?'
The most common real-world use of class methods is the convenience constructor pattern, such as +[NSArray arrayWithObjects:...] or +[UIColor colorWithRed:green:blue:alpha:], which internally call alloc and an instance-level init... method and hand back an already-configured, often autoreleased, instance. Writing your own convenience class method typically looks like + (instancetype)personWithName:(NSString *)name returning [[self alloc] initWithName:name], using self (which refers to the class itself inside a class method) rather than hardcoding the class name, so subclasses inherit correct behavior.
Cricket analogy: A convenience class method is like a franchise's front office handing you a fully assembled squad ('here's your XI') rather than making you draft each player individually — +teamWithRoster: wraps up alloc+init into one call.
self inside class methods vs instance methods
Inside an instance method, self refers to the specific object instance the message was sent to; inside a class method, self refers to the class object itself (an instance of the metaclass). This distinction matters most for inheritance: writing + (instancetype)sharedInstance { return [[self alloc] init]; } correctly allocates a subclass's own type when called as [MySubclass sharedInstance], whereas hardcoding [MyBaseClass alloc] would always allocate the base class even when called through a subclass — a subtle bug that breaks polymorphic class methods.
Cricket analogy: Using self in a class method is like a franchise's academy producing whichever specific team's kit is requested ('Mumbai Indians' vs 'Chennai Super Kings'), rather than a hardcoded factory that always stamps out Mumbai gear regardless of who ordered it.
@interface Shape : NSObject
@property (nonatomic) CGFloat area;
+ (instancetype)shapeWithArea:(CGFloat)area; // class (convenience constructor)
- (void)describe; // instance method
@end
@implementation Shape
+ (instancetype)shapeWithArea:(CGFloat)area {
// 'self' here is the class object; works correctly for subclasses too
Shape *shape = [[self alloc] init];
shape.area = area;
return shape;
}
- (void)describe {
// 'self' here is the specific instance
NSLog(@"A %@ with area %.2f", NSStringFromClass([self class]), self.area);
}
@end
@interface Circle : Shape
@end
@implementation Circle
@end
// [Circle shapeWithArea:] correctly returns a Circle instance, not a Shape,
// because the class method uses 'self' rather than a hardcoded [Shape alloc].
Circle *c = [Circle shapeWithArea:78.5];
[c describe]; // "A Circle with area 78.50"Class methods can access class-scoped storage using a static variable declared inside the .m file (a common pattern for a singleton's shared instance), since Objective-C has no direct equivalent of Java's static fields on the class itself.
A class method cannot directly access an instance's ivars or call an instance method without first having a specific instance reference, since there's no implicit 'self' instance inside a class method — only the class object.
-denotes an instance method, operating on a specific object's state.+denotes a class method, callable on the class itself without an instance.- Class methods commonly implement convenience constructors that wrap alloc/init.
- Inside a class method,
selfrefers to the class object, enabling correct subclass behavior. - Using
[self alloc]instead of a hardcoded class name keeps factory methods polymorphic. - Class methods cannot directly access instance ivars without an explicit instance reference.
- Objective-C classes are themselves objects of a metaclass, so class methods are dynamically dispatched too.
Practice what you learned
1. What does the `+` prefix indicate on an Objective-C method declaration?
2. Inside a class method implemented with `[self alloc]`, what does self refer to when called via a subclass?
3. Why is [self alloc] preferred over a hardcoded [BaseClassName alloc] inside a convenience class method?
4. Can a class method directly access an instance's ivars?
5. What is the most common real-world use case for class methods in Objective-C?
Was this page helpful?
You May Also Like
Methods and Message Passing
Explore how Objective-C methods work as messages sent to objects at runtime, including selectors, method signatures, and dynamic dispatch.
Blocks in Objective-C
Learn how Objective-C blocks capture surrounding variables as closures, how __block and __weak change capture behavior, and how to avoid retain cycles.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics