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

Protocols and Delegation

How @protocol defines interface-like contracts in Objective-C, and how the delegation pattern uses protocols to decouple objects.

OOP in Objective-CIntermediate10 min readJul 10, 2026
Analogies

Protocols and Delegation

A protocol, declared with @protocol ProtocolName ... @end, defines a list of method signatures that any class can promise to implement without dictating what that class inherits from, which is Objective-C's answer to interfaces in languages like Java. A class declares conformance by listing the protocol name in angle brackets after its superclass, @interface FileDownloader : NSObject <URLSessionDownloadDelegate>, and the compiler then checks that the class actually implements every required method the protocol declares.

🏏

Cricket analogy: Like an ICC-certified umpire qualification that any official can earn regardless of which cricket board they belong to, a protocol defines a set of responsibilities any class can adopt regardless of what it inherits from.

Required and Optional Protocol Methods

By default, every method listed in a protocol is @required, meaning any conforming class must implement it or the compiler emits a warning, but methods after an explicit @optional marker are not mandatory, and calling an optional method safely requires checking [delegate respondsToSelector:@selector(methodName)] first to avoid sending a message the object doesn't implement. This required/optional split is exactly how UIKit's table view and text field delegates work: cellForRowAtIndexPath: is required for a UITableViewDataSource to function at all, while textFieldShouldReturn: is optional and only called if the delegate chose to implement it.

🏏

Cricket analogy: Like an ICC playing-conditions rulebook marking the toss and the scorecard as mandatory for every match while marking DRS reviews as optional depending on the series agreement, protocols mark some methods @required and others @optional.

Delegation: Protocols in Practice

Delegation is the design pattern where one object (the delegate) is handed responsibility for certain decisions or notifications on behalf of another object, and it's implemented by declaring a weak property typed as id<SomeProtocol> on the object doing the delegating, so that object can call methods on whatever delegate object was assigned to it without knowing or caring about that delegate's concrete class. The delegate property is declared weak rather than strong specifically to avoid a retain cycle, since the delegating object typically also being retained by the delegate (directly or indirectly) would otherwise create two objects each keeping the other alive forever.

🏏

Cricket analogy: Like a captain delegating the decision of when to review a decision via DRS to a specific senior player on the field, without needing to know their batting technique, only that they can make that specific call, delegation hands one specific responsibility to any object conforming to the right protocol.

objectivec
// DownloadTaskDelegate.h
@protocol DownloadTaskDelegate <NSObject>
@required
- (void)downloadTask:(id)task didFinishWithData:(NSData *)data;
@optional
- (void)downloadTask:(id)task didUpdateProgress:(float)progress;
@end

// DownloadTask.h
@interface DownloadTask : NSObject
@property (nonatomic, weak) id<DownloadTaskDelegate> delegate;
- (void)start;
@end

// DownloadTask.m
@implementation DownloadTask
- (void)start {
    NSData *result = [self fetchData];
    if ([self.delegate respondsToSelector:@selector(downloadTask:didUpdateProgress:)]) {
        [self.delegate downloadTask:self didUpdateProgress:1.0];
    }
    [self.delegate downloadTask:self didFinishWithData:result]; // required, always safe to call
}
@end

// ViewController.m adopts the protocol
@interface ViewController () <DownloadTaskDelegate>
@end

@implementation ViewController
- (void)startDownload {
    DownloadTask *task = [[DownloadTask alloc] init];
    task.delegate = self;
    [task start];
}
- (void)downloadTask:(id)task didFinishWithData:(NSData *)data {
    NSLog(@"Download finished with %lu bytes", (unsigned long)data.length);
}
@end

A protocol can itself inherit from other protocols, for example @protocol MyDataSource <NSObject> ensures any class conforming to MyDataSource is also guaranteed to respond to NSObject's own methods like description and respondsToSelector:, which is why nearly every custom protocol you write should inherit from NSObject.

Declaring a delegate property as strong instead of weak is a classic retain-cycle bug: if the delegating object (like DownloadTask) is strongly retained by its delegate (like a ViewController holding onto its task), and the task also strongly retains the delegate back, neither object's memory is ever released.

  • A protocol declares method signatures with @protocol...@end without dictating a class's inheritance.
  • A class adopts a protocol by listing it in angle brackets after its superclass, e.g. <DownloadTaskDelegate>.
  • Methods are @required by default; methods after @optional are not mandatory to implement.
  • respondsToSelector: should be checked before calling an optional protocol method.
  • Delegation hands specific decisions to another object typed as id<ProtocolName>, decoupling concrete classes.
  • Delegate properties are declared weak to avoid retain cycles between the delegating object and its delegate.
  • Protocols can inherit from other protocols, most commonly from NSObject.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#ObjectiveCStudyNotes#ProtocolsAndDelegation#Protocols#Delegation#Required#Optional#StudyNotes#SkillVeris#ExamPrep