I think you didn't fully get the understanding what protocols are.
I always say protocols are like contracts.
The delegate object that implements a certain protocols promises that it can do things the delegator can't do.
In real world I have a problem with my house's tubes.
I (the delegator) call a plumber (the delegate) to fix it. The plumber promises (by contract) to be able to duo it. The promise is the protocol. I don't care how he do it, as long as he does it.
But these contracts are not only useful for delegation.
I am just writing a food ordering app. As it has a menu it need item to display in it.
I could go with basic inheritance and write a class MenuItem, that all sub classes must inherit from.
Or I write an protocol to express: «No matter what object you are, as long as you fulfill this contract we have a deal». this allows me to create many different classes or annotate existing classes in categories, although I don't have the tool of multiple inheritance.
Actually I do both: I write a protocol MenuItem
and a class MenuItem
that conforms to the protocol. Now I can use simple inheritance or use classes that do not inherit from the class MenuItem
.
Code in Objective-C (sorry: I am still transitioning to Swift)
@protocol MenuItem <NSObject>
-(NSString *)name;
-(double) price;
-(UIColor *)itemColor;
@end
@interface MenuItem : NSObject <MenuItem>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) double price;
@property (nonatomic, strong) UIColor *itemColor;
@end
#import "MenuItem.h"
@implementation MenuItem
-(id)initWithCoder:(NSCoder *)decoder
{
self = [super init];
if (self) {
self.name = [decoder decodeObjectForKey:@"name"];
self.price = [decoder decodeDoubleForKey:@"price"];
self.itemColor = [decoder decodeObjectForKey:@"itemColor"];
}
return self;
}
-(void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeDouble:self.price forKey:@"price"];
[encoder encodeObject:self.name forKey:@"name"];
[encoder encodeObject:self.itemColor forKey:@"itemColor"];
}
@end
Apple uses the same Architecture for NSObject: there is a protocol and a class NSObject
. This allows classes, that aren't intact inheriting from the class NSObject
to act ash an NSObject. One famous example:NSProxy
.
in your case Screen1 promises to be able to understand messages that are send by the detail view controller Screen2. These allows decoupling: any object that does understand Screen1's protocol can be used. Also it helps to maintain a sane object tree, as we don't have to have circular imports. But in general you have to keep in mind that the delegator (Screen2) must keep a weak reference to it's delegate, otherwise we have a retain circle.
Of course an important example it UITableView:
The table view object knows everything about rendering it's cells, handling scrolling and so one. But the engineer who wrote it couldn't now how you want your table view look like. That's why he introduced a delegate to give you the chance to create the right cell. As he couldn't also know what your data looks like, he also introduced the datasource - that works exactly like a delegate: you will be asked to provide all information about your data, that are needed.