Objective-C is a language versatile and sophisticated enough for iOS and Mac OS GUI programming. One Objective-C feature that can be called both flexible and dynamic is the use of protocols. Protocols help in the creation of interfaces where a class implementation needs to follow a set of methods and properties.
What are the Protocols in Objective-C?
A protocol is a normative approach to constrain a set of classes that may require a common interface, for instance, delegates, data sources, and observers.
- This approach can also integrate secondary, or multiple, inheritance which is not permitted when working with Cocoa classes.
- A single class can be responsible for multiple protocols, which means it can easily adapt the behavior of several other classes without necessarily subclassing these classes.
Types of Protocols in Objective-C
There are two types of protocols in Objective-C, formal and informal protocols.
Formal Protocols
In the formal protocol declaration, the name of the protocol and its methods and properties are used after the prefix @protocol. Protocols declare methods and properties with modifiers, like @required or @optional, to indicate the needed implementation by the classes that accept the protocol. After this, the @end statement must appear. It marks the end of the protocol declaration.
For instance, the below code defines an arbitrary protocol called PrintProtocolDelegate, specifically, in which it declares a single necessary method called processCompleted.
ObjectiveC
@protocol PrintProtocolDelegate
@required
- (void)processCompleted;
@end
A class can accept a formal protocol by specifying the protocol name in angle brackets after the class name in the interface declaration. For example, the following code defines a class named SampleClass
that accepts the PrintProtocolDelegate
protocol.
ObjectiveC
@interface SampleClass : NSObject <PrintProtocolDelegate>
// class methods and properties
@end
When accepted, a class commits a contract to abide by the introduced methods and properties in the protocol. If a class does not behave according to an interface that a certain method or property says it must, the compiler will provide a warning message. This class does internal magic by creating the ability to choose from the mentioned methods and properties, purely based on the functionality desired.
We can declare either a variable or a parameter and assign it an object of any class that incorporates the protocol to a protocol type using the protocol. Saying that the code below defines a class referred to as PrintClass with a property set as the delegate of the type id<PrintProtocolDelegate>. This, therefore, means that the delegate property can hold a reference to any type that is an object of the PrintProtocolDelegate protocol.
ObjectiveC
@interface PrintClass : NSObject
@property (nonatomic, weak) id<PrintProtocolDelegate> delegate;
// class methods and properties
@end
The PrintClass can then use the delegate property to invoke the methods and properties defined by the protocol. For example, the following code shows how PrintClass can call the processCompleted method on its delegate object after printing some details.
ObjectiveC
@implementation PrintClass
- (void)printDetails {
NSLog(@"Printing Details");
[self.delegate processCompleted];
}
@end
The delegate property can be set to any object that implements the PrintProtocolDelegate protocol. For example, the following code shows how the SampleClass can set itself as the delegate of a PrintClass object and implement the processCompleted method.
ObjectiveC
#import <Foundation/Foundation.h>
@protocol PrintClassDelegate <NSObject>
- (void)processCompleted;
@end
@interface PrintClass : NSObject
@property (nonatomic, weak) id<PrintClassDelegate> delegate;
- (void)printDetails;
@end
@implementation PrintClass
- (void)printDetails {
// Add your print details logic here
[self.delegate processCompleted];
}
@end
@interface SampleClass : NSObject <PrintClassDelegate>
- (void)startAction;
@end
@implementation SampleClass
- (void)startAction {
PrintClass *printClass = [[PrintClass alloc] init];
printClass.delegate = self;
[printClass printDetails];
}
- (void)processCompleted {
NSLog(@"Printing Process Completed");
}
@end
int main() {
SampleClass *sampleClass = [[SampleClass alloc] init];
[sampleClass startAction];
return 0;
}
Output:

Informal Protocols
That is not to say that informal protocols are not declared, just that the declaration of informal protocols employs the category of the NSObject class in place of @protocol.
- "Categories are a way of adding methods to the existing class without its subclassing" – groups methods that don’t add new behaviors to the original class.
- A non-official protocol is a list of rules that are not required by classes to implement, but they are expected to be available while the classes are under execution.
As an instance, the MyProtocol protocol has been formally declared in a category of the NSObject class, which is not as strict from an informal protocol standpoint. The protocol declares two methods: doSomething and doSomethingElse, on the other hand, which involves the organization of citizen groups for individual and collective actions.
ObjectiveC
@interface NSObject (MyProtocol)
- (void)doSomething;
- (void)doSomethingElse;
@end
A class can accept an informal protocol by implementing the methods defined by the protocol in its interface or implementation. This has no protocol name specified in the class declaration For instance, the following code shows the MyClass class that uses the MyProtocol unwritten protocol by implementing the doSomething method:
ObjectiveC
@interface MyClass : NSObject
// class methods and properties
@end
@implementation MyClass
- (void)doSomething {
NSLog(@"Doing something");
}
@end
To have an informal protocol, we will declare a variable or a parameter of the type id and then assign it an object of any class that may accept the protocol. For example, the below code defines a function callProtocolMethod which accepts parameters of the type id as input and calls the method doSomething to the parameter:
ObjectiveC
void callProtocolMethod(id object) {
[object doSomething];
}
The object parameter can be an object of anything that lists the `doSomething` method. In another case, the callProtocolMethod function might be used as shown in the code below when the class MyClass object is being passed.
ObjectiveC
int main(int argc, const char * argv[]) {
MyClass *myObject = [[MyClass alloc] init];
callProtocolMethod(myObject);
return 0;
}
Usually, informal protocols have faced a deficit of popularity to official protocols and they are only used for continuation with the previous versions of Objective-C. They have some drawbacks, such as
- They are however checked by the compiler, therefore programs may contain the methods even though the particular classes that are accepting them do not implement them at all.
- They don't correspond to the function declarations as returned by the header files so they are substantially more difficult to identify and apply.
- These collisions result from the repeated use of names that are the same but possess various signatures or connotations.
From this, a suggestion is drawn that a formal protocol should be used as it will largely fit more to safety, clarity, and consistency.
Syntax and Keywords
The following table summarizes the syntax and keywords related to protocols in Objective-C:
Syntax/Keyword
| Description
|
---|
@protocol ProtocolName
| Starts the declaration of a formal protocol with the given name.
|
---|
@end
| Ends the declaration of a protocol or a class.
|
---|
@required
| Marks the following methods and properties as required to be implemented by the classes that accept the protocol. This is the default modifier if none is specified.
|
---|
@optional
| Marks the following methods and properties as optional to be implemented by the classes that accept the protocol.
|
---|
<ProtocolName>
| Specifies that a class or a variable conforms to the protocol with the given name.
|
---|
id<ProtocolName>
| Declares a variable or a parameter of the type ID that conforms to the protocol with the given name.
|
---|
@protocol(ProtocolName)
| Returns the Protocol object that represents the protocol with the given name.
|
---|
conformsToProtocol:
| Returns a Boolean value that indicates whether an object conforms to a given protocol.
|
---|
respondsToSelector:
| Returns a Boolean value that indicates whether an object responds to a given selector.
|
---|
Examples
Here are examples of Objective-C protocols and their application as well as associated advantages.
Example 1: NSCopying Protocol
The NSCopying protocol is, by definition, a formal protocol that describes how one should do copying for an object. The protocol declares a single required method: copyWithZone:. This agreement has to be corrected by any class that is for copying and this this particular method is to be well executed.
For example, the following code defines a class named Person that accepts the NSCopying protocol and implements the copyWithZone: the solution. The method thereby inverts a new Person object that has the same name and age as the original object, assigning it to a new Person object and returning it.
ObjectiveC
@interface Person : NSObject <NSCopying>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end
@implementation Person
- (id)copyWithZone:(NSZone *)zone {
Person *copy = [[Person allocWithZone:zone] init];
copy.name = self.name;
copy.age = self.age;
return copy;
}
@end
The Person class can be used with methods and classes that have a requirement that the objects be copyable, like NSArray, NSDictionary, or NSKeyedArchiver, and the NSCopying protocol can be used for this purpose. For another example, the following code depicts the operation of copying the Person class to an array and adding the Person class by the following methods.
The Person class can be copied and used as a means of storage for later use.
ObjectiveC
int main(int argc, const char * argv[]) {
Person *person1 = [[Person alloc] init];
person1.name = @"Alice";
person1.age = 25;
Person *person2 = [person1 copy]; // create a copy of person1
person2.name = @"Bob"; // change the name of person2
NSArray *array = @[person1, person2]; // add both objects to an array
for (Person *person in array) {
NSLog(@"Name: %@, Age: %ld", person.name, person.age);
}
return 0;
}
Output:

This output shows that the person1
and person2
objects are different and independent copies, as changing the name of person2
does not affect the name of person1
.
Example 2: NSCoding Protocol
The NSCoding
protocol is a formal protocol that defines methods for encoding and decoding objects. The protocol declares two required methods: initWithCoder:
and encodeWithCoder
:
. Any class that wants to support archiving and unarchiving must accept this protocol and implement these methods.
For example, the following code defines a class named Student
that accepts the NSCoding
protocol and implements the initWithCoder
:
and encodeWithCoder:
methods. The methods encode and decode the name and grade properties of the Student
object using the NSCoder
object.
ObjectiveC
@interface Student : NSObject <NSCoding>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger grade;
@end
@implementation Student
- (instancetype)initWithCoder:(NSCoder *)coder {
self = [super init];
if (self) {
self.name = [coder decodeObjectForKey:@"name"];
self.grade = [coder decodeIntegerForKey:@"grade"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:self.name forKey:@"name"];
[coder encodeInteger:self.grade forKey:@"grade"];
}
@end
With several built-in protocols at one's service, utilization of the NSCoding protocol enables Student class to be used with classes and methods that require codable objects, like NSKeyedArchiver, NSKeyedUnarchiver, or NSUserDefaults. Here is the code that shows that the student can be archived as unarchived using NSKeyedArchiver and NSKeyedUnarchiver classes:
ObjectiveC
int main(int argc, const char * argv[]) {
Student *student1 = [[Student alloc] init];
student1.name = @"Charlie";
student1.grade = 10;
// archive the student1 object to a file
NSString *filePath = @"/Users/Desktop/student1.dat";
BOOL success = [NSKeyedArchiver archiveRootObject:student1 toFile:filePath];
if (success) {
NSLog(@"Archived successfully");
}
// unarchive the student1 object from the file
Student *student2 = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
if (student2) {
NSLog(@"Unarchived successfully");
NSLog(@"Name: %@, Grade: %ld", student2.name, student2.grade);
}
return 0;
}
Output:

Through this, the personals are understood that the student1 as well as student2 objects are the same and have a common name and grade properties.
Example 3: Custom Protocol
Also, we can generate custom protocols that will be struggling to solve a particular need. For example, the following code defines a custom protocol named MathProtocol that declares two optional methods: multTwoNum: and addTwoNum. It indicates also the declaration of the result property that is required. Listen to the given audio and complete the sentence with the missing phrase.
ObjectiveC
@protocol MathProtocol
@optional
- (void)addTwoNumbers:(NSArray *)numbers;
- (void)multiplyTwoNumbers:(NSArray *)numbers;
@required
@property (nonatomic, assign) NSInteger result;
@end
The below code declares a class named Calculator which accepts the MathProtocol protocol and accords with the specified functions and properties. The operations involved here are simple and involve the entirety of the given numbers. Finally, as a result of the equations, a number is stored in its property.
ObjectiveC
@interface Calculator : NSObject <MathProtocol>
@property (nonatomic, assign) NSInteger result;
@end
@implementation Calculator
- (void)addTwoNumbers:(NSArray *)numbers {
NSInteger sum = 0;
for (NSNumber *number in numbers) {
sum += [number integerValue];
}
self.result = sum;
}
- (void)multiplyTwoNumbers:(NSArray *)numbers {
NSInteger product = 1;
for (NSNumber *number in numbers) {
product *= [number integerValue];
}
self.result = product;
}
@end
The text below describes the use of the Calculator class with the MathProtocol protocol which is given in the following code.
ObjectiveC
int main(int argc, const char * argv[]) {
Calculator *calculator = [[Calculator alloc] init];
// check if the calculator object responds to the addTwoNumbers: method
if ([calculator respondsToSelector:@selector(addTwoNumbers:)]) {
[calculator addTwoNumbers:@[@2, @3, @4]]; // call the method with an array of numbers
NSLog(@"The sum is %ld", calculator.result); // print the result
}
// check if the calculator object responds to the multiplyTwoNumbers: method
if ([calculator respondsToSelector:@selector(multiplyTwoNumbers:)]) {
[calculator multiplyTwoNumbers:@[@2, @3, @4]]; // call the method with an array of numbers
NSLog(@"The product is %ld", calculator.result); // print the result
}
return 0;
}
Output:

This means that the calculator object is compatible with the MathProtocol protocol and provides the default methods and the required properties.
Conclusion
Protocols is a beneficial low-level Objective-C feature that lets define a set of methods and properties that a class should implement. Inheritance protocols allow us to design a shared front end for some classes, to maintain several inheritances, and to provide copying, coding, and other functionalities subtly. The protocols can be informal/ formal and are mandatory/non-obligatory. Protocols may be created and utilized with correct keywords and syntax. As well, we will also be able to customize protocols to their matching our highly individual needs and specifications. Protocols serve as a useful instrument for making applications dynamic and flexible in Objective-C.
Similar Reads
Pointer to Arrays in Objective-C
In Objective-C, a pointer to an array is a way to store multiple values of the same data type in contiguous memory locations. These arrays can be manipulated and accessed using pointers, which are variables that store the memory address of another variable. In Objective-C, pointers to arrays are use
4 min read
What are the protocols used by Ajax ?
In this article we will go to cover what really Ajax means, Asynchronous, and how it makes requests to the server using XMLHTTPRequest and the protocols used by ajax, basically HTTP and HTTPS. AJAX: AJAX stands for Asynchronous JavaScript And XML. It is about updating a web page without reloading th
4 min read
Properties in Objective-C
The object-oriented programming language Objective-C is largely used to create applications for Apple's macOS and iOS platforms. It incorporates all of the characteristics of C while also providing more features for object-oriented programming, making it a superset of the C programming language. The
5 min read
Text and strings Storage in Objective C
Objective-C is an object-oriented programming language widely used to develop programs for iOS and macOS. This article focuses on discussing how text and string data can be stored in Objective-C. Types and Subtypes of Strings Objective-C has two main types of strings - NSString and NSMutableString.
3 min read
What is Internet Protocol (IP)?
The Internet Protocol (IP) is a set of rules that allows computers and other devices to communicate over the Internet. It ensures that information sent from one device reaches the correct destination by using a unique set of numbers known as IP addresses. Whether you're browsing websites, sending em
7 min read
Structures in Objective-C
Objective-C is an object-oriented programming language that adds small talk-style messaging to the C programming language. Follows a bottom-up programming approach. It incorporates concepts from both procedural and object-oriented programming languages. Objective-C support structures. So in this art
5 min read
Why is TCP Called a Connection Oriented Protocol?
TCP is a standard connection-oriented protocol that works under the following conditions before any transmission takes place between both devices: Establish a logical connection with the device on receiver's end The Transmission Control Protocol (TCP) is a protocol of the transport layer, which is t
4 min read
Polymorphism in Objective-C
One of the fundamental concepts in object-oriented programming is polymorphism. It enables objects to take on a variety of forms depending on their context. In Objective-C, polymorphism allows a class to have multiple behaviors depending on the type of data it is acting on. It is one of the key char
4 min read
Variables in Objective-C
A variable is a place for data storage that our programs can access or manipulate. In Objective-C, variables have a defined type that specifies their shape and layout. They also cover the gamut of values and operations that we are capable of performing. Before moving further, we understand the guide
5 min read
Strings in Objective-C
Strings are a fundamental concept in programming, and they are used to represent text in many different applications. In Objective-C, a string is an object that represents a sequence of characters. A string can be created using several built-in classes and methods, which allow you to manipulate the
4 min read