Defining Property Requirements in Objective-C Protocols
Understanding Prootcol Property Declarations
Objective-C protocols define method contracts rather than implementations. Since protocols serve as interface specifications, they cannot contain stored properties—the actual storage must be provided by conforming classes.
Protocols can, however, declare property requirements. When you specify a property in a protocol, you're essentially requiring conforming classes to implement the corresponding getter and setter methods.
Declaring Properties in a Protocol
Property declarations in protocols use the @property syntax. The implementing class must then provide the actual storage and accessor implementations.
@protocol Drawable <NSObject>
@property (nonatomic, copy) NSString *title;
@property (nonatomic, readonly) NSInteger identifier;
@property (nonatomic, assign, getter=isVisible) BOOL visible;
@end
This protocol declares three property requirements that any conforming class must fulfill.
Implementing Protocol Properties
When a class conforms to a protocol with property requirements, it must provide backing storage and accessors. There are two approaches:
Automatic Synthesis with @synthesize
@interface Shape : NSObject <Drawable>
// No need to redeclare protocol properties
@end
@implementation Shape
@synthesize title = _title;
@synthesize identifier = _identifier;
@synthesize visible = _visible;
@end
Manual Accessor Implementation
@implementation Shape
- (instancetype)init {
self = [super init];
if (self) {
_identifier = 0;
_visible = YES;
}
return self;
}
- (NSString *)title {
return _title;
}
- (void)setTitle:(NSString *)title {
_title = [title copy];
}
- (NSInteger)identifier {
return _identifier;
}
- (BOOL)isVisible {
return _visible;
}
- (void)setVisible:(BOOL)visible {
_visible = visible;
}
@end
Key Considerations
Property declarations in protocols are fundamentally method declarations—the compiler treats @property (nonatomic, readonly) NSString *name as requiring both a -name getter and potentially a -setName: setter depending on the attributes.
Since protocols do not provide storage, you must ensure implementing classes declare instance variables or use backing ivars through synthesis. Modern Objective-C (Xcode 4.4+) automatically synthesizes properties declared in the @interface, creating backing ivars with underscore prefixes, so explicit @synthesize is often unnecessary.
Protocol property declarations enhance type safety and provide clear documentation of interface requirements, making them invaluable for designing cohesive class hierarchies and enforcing consistent interfaces across unrelated classes.