What is the Objective-C syntax for multiple protocols?
Could you please elaborate on your question? Otherwise this is the proper way to declare a class that conforms to multiple protocols. You specify the protocols a class conforms to after the superclass declaration in a classes header file.
#interface MyClass : MySuperClass <Delegate1, Delegate2, Delegate3> {
//instance variables
}
//properties
//methods
You can achieve multiple protocols in two ways:
Method 1
#protocol p1 <NSObject>
-(void)M1
-(void)M2
#end
#protocol p2 <NSObject>
-(void)M3
-(void)M4
#end
#interface MyViewController () <p1,p2>
Method 2
#protocol p1 <NSObject>
-(void)M1
-(void)M2
#end
#protocol p2 <NSObject,p1>
-(void)M3
-(void)M4
#end
#interface MyViewController () <p1>
For an object to have multiple delegates (as opposed to being a delegate for multiple objects or classes):
The object delegating would have to
have an NSArray of delegate instance
variables.
The setDelegate setter method would
then have to add a delegate object
to this array instead of just
assigning it to one instance
variable.
The send-to-delegate code would have
to loop through the delegate
NSArray, instead of checking for
just one delegate instance variable
to be non-nil, before checking for
message handling and calling out
with the message.
Nothing much would change in all the objects or the class asking for delegation to itself.
Yes, I guess the question of comfort to multi protocols is something like the following:
#interface MyViewController () <protocol1, protocol2, protocol3>
Related
Ok, there are several questions with "Protocol" and "Inheritance" but I can't really find the answer to my question. I have a class with a protocol. For example:
#class SomeClass;
#protocol SomeDelegate <NSObject>
#optional
-(void) someMethod;
#end
#interface SomeClass : NSObject
{
id<SomeDelegate> delegate;
}
#property id<SomeDelegate> delegate;
-(void) thisDoesStuff;
#end
Then I have a different class whose object will be a delegate of a SomeClass object:
#interface DiffClass: SomeClass<SomeDelegate>
// This method will conform to the one specified on the protocol
-(void) someMethod;
#end
My question is, does DiffClass inherit from SomeClass? I'm considering the syntax in Objective C for inheritance:
#interface ClassA : SuperClassOfClassA
Where, in the above, ClassA inherits from SuperClassOfClassA.
Additionally, in Objective C, is it possible to inherit from one class and adopt a protocol from a different class? I guess what I'm trying to get at is if it's possible that two objects are able to communicate to each other through delegates without having to inherit from that protocol's class (I hope I'm making sense).
Thanks in advance!
In practice, your code would be very strange.
First, you don't have a class with a protocol. You have a protocol named SomeDelegate. Then you have a class SomeClass, which is unrelated to the protocol. Well, it has an instance variable that supports SomeDelegate, but that has nothing to do with the protocol.
Then you create a class that is both a subclass of SomeClass, and supports the SomeDelegate protocol. That's unusual. I mean DiffClass both supports the protocol itself, and has a delegate supporting the protocol. That's a bit strange.
Nevertheless, DiffClass is a subclass of SomeClass, and you promised that it supports the protocol SomeDelegate, so that's fine.
But really: A protocol doesn't belong to a class. I don't know what made you think that, but you have to remove that from your brain immediately. A protocol is a totally different thing and totally independent from a class. It's a set of requirements that any class may or may not fulfil. It exists independent of any class. Because a protocol is a set of requirements, a class can support that protocol by claiming it does (adding ) and by adding the required methods.
To answer your first question, DiffClass does inherit from SomeClass as you have it written. But it doesn't need to inherit from SomeClass. I'll be a bit more thorough below.
A protocol is a declaration of methods (and properties) that a class adopts. It does not have to be related to a class, although it often is for the delegation pattern.
For example, you could have a header that just declares a protocol. Let's call the file NewProtocol.h
#protocol NewProtocol<NSObject>
#optional
- (void)newMethod;
#end
Then any class can adopt that protocol. With your example above, this could be DiffClass. You do not need to declare the methods from NewProtocol again in the class interface.
// You would need to import NewProtocol.h
// Note that this does NOT inherit from SomeClass.
#interface DiffClass : NSObject<NewProtocol>
#end
Then the implementation of DiffClass would need to provide the declared protocol methods.
#implementation DiffClass
- (void)newMethod {
// Do stuff.
}
#end
Then SomeClass could have a property for the declared protocol above.
#interface SomeClass : NSObject
// Often you will want weak for delegates as they can cause retain cycles otherwise.
#property(nonatomic, weak) id<NewProtocol> thingThatImplementsNewProtocol;
-(void) thisDoesStuff;
#end
DiffClass does now NOT inherit from SomeClass but can be used to communicate with SomeClass. You could declare a second protocol that SomeClass adopts and a property on DiffClass to have two way communication.
Often the protocol are declared in the same header file as a class for simplicity because they are intended as delegates for specific objects.
Answer to the question 1: with the statement
#interface DiffClass: SomeClass<SomeDelegate>
The DiffClass inherits from SomeClass and also conforms the protocol(interface) SomeDelegate.
Answer to the question 2: In Objc you can inherit only from one parent class (multiple inheritance wont be supported) but you can conform as many as protocols (interfaces) you want.
Lets take and example of an drawing App. Shape is a parent class and RectangleShape, LineSahpe, TextShape, CircleShape are the children from Shape class. All four children are inheriting from their parent Shape. But you need to move the shape except LineShape. There you can have protocol (interface) as Movable. That you can do so.
#protocol Movable <NSObject>
#end
#interface Shape : NSObject
#end
#interface RectangleShape : Shape <Movable>
#end
#interface LineSahpe : Shape // cannot be moved, just for an example.
#end
#interface TextShape : Shape <Movable>
#end
#interface CircleShape : Shape <Movable>
#end
You can have a method for the protocol like this to move all Shaped which are conforming Movable protocol (interface).
- (void)move:(id <Movable>)movableShape {
}
You can implement a communication instead of moving shapes. Protocols are really useful during advanced programming.
Hope it will help you... please feedback me.
Is it possible for a class to conform to more than one protocol in objective-c? If so,
what is the syntax for declaring a class that conforms to more than one protocol?
#interface MyClass : NSObject <Protocol1, Protocol2, Protocol3>
#end
Yes; Just put a comma between each Protocol.
Yes it is possible for a class to conform to multiple protocols. The syntax is as follows:
#interface MyClass : NSObject <Protocol1, Protocol2, Protocol3>
//...Some code here...
#end
A protocol in Objective-C is essentially a list of methods which must be implemented in order for an object or class to be said to be conforming to that protocol. A common example of a class conforming to multiple protocols is a UITableViewController that acts as a UITableViewDataSource and a UITableViewDelegate.
For a UITableViewController example, it might look like this:
#interface MyTableViewController : UITableViewController <UITableViewDataSource, UITableViewDelegate>
//...Some code here...
#end
You separate each protocol with a comma, and put it inside of those brackets. When you add those protocols to your interface declaration, you're essentially saying "yes, I'll implement the methods defined by those protocols". Now, go ahead and implement those methods, or the compiler will remind you that you haven't kept your word.
I've seen Objective-c protocols defined in the following way:
#protocol MyProtocol <SomeOtherProtocol>
// ...
#end
Why do protocols adopt other protocols? I'm especially curious why a protocol would adopt the NSObject protocol.
It is simply the same concept as inheritance for classes.
If a protocol adopt another protocol, it "inherits" the declared methods of this adopted protocol.
The NSObject protocol especially declares methods such as respondsToSelector:. So this is especially useful if you declare a #protocol that have #optional methods, because when you will then call methods on objects conforming this protocol, you will need to check if the object responds to the method before calling it if this method is optional.
#protocol SomeProtocol <NSObject>
-(void)requiredMethod;
#optional
-(void)optionalMethod;
#end
#interface SomeObject : NSObject
-(void)testMyDelegate;
#property(nonatomic, assign) id<SomeProtocol> myDelegate;
#end
#implementation SomeObject
#synthesize myDelegate
-(void)testMyDelegate {
// Here you can call requiredMethod without any checking because it is a required (non-optional) method
[self.myDelegate requiredMethod];
// But as "optionalMethod" is #optional, you have to check if myDelegate implements this method before calling it!
if ([myDelegate respondsToSelector:#selector(optionalMethod)]) {
// And only call it if it is implemented by the receiver
[myDelegate optionalMethod];
}
}
#end
You will only be able to call respondsToSelector on myDelegate if myDelegate is declared as a type that implements respondsToSelector (otherwise you will have some warnings). That's why the <SomeProtocol> protocol needs to adopt itself the <NSObject> protocol, which itself declares this method.
You may think of id<SomeProtocol> as "any object, whatever its type (id), it just has to implement the methods declared in SomeProtocol, including the methods declared in the parent protocol NSObject. So it can be an object of any type but because SomeProtocol adopts the NSObject protocol itself, it is guaranteed that you are allowed to call respondsToSelector on this object, allowing you to check if the object implements a given method before calling it if it is optional.
Note that you may also not make SomeProtocol adopt the NSObject protocol and instead declare your variable as id<SomeProtocol,NSObject> myDelegate so that you can still call respondsToSelector:. But if you do that you will need to declare all your variables this way everywhere you use this protocol... So this is much more logical to make SomeProtocol directly adopt the NSObject protocol ;)
Inheritance...................
Well, I have these two protocols:
#protocol ivAuthorizationProtocol <NSObject>
-(void)loginReply:(ivSession*)session;
#end
#protocol ivServerListsProtocol <NSObject>
-(void)serverListLoaded:(NSArray*)serverList;
#end
and have class
#interface ivClientAppDelegate : NSObject <UIApplicationDelegate>
...
#end
#implementation
...
-(void)authorizeWithLogin:(NSString*)login andPassword:(NSString*)password
{
self.login = login;
self.password = password;
// !!! delegate in the next call should conform to ivAuthorizationProtocol,
// so i get warning "class does not implement protocol ivAuthoriaztionProtocol" here
[_apiWrapper authorizeWith:login andPassword:password forDelegate:self];
}
...
#end
I want to put the implementation of the protocol's methods in separate files (categories) so not to mess up the main implementation file. For example, the header of the category for implementation of ivAuthorizationProtocol looks like this:
#import "ivClientAppDelegate.h"
#interface ivClientAppDelegate (ivAuthorizationResponder) <ivAuthorizationProtocol>
-(void)loginReply:(ivSession*)session;
#end
So, the question is - how can I get rid of the warning I get in the main implementation file? How can I tell the compiler that methods conforming to the protocol are located in categories?
Thanks in advance!
You could use a cast to silence the warning:
[_apiWrapper
authorizeWith:login
andPassword:password
forDelegate:(id<ivAuthorizationProtocol>)self
];
Other than that, you can't do what you want without getting different warnings (unimplemented methods). Normally you would specify the protocol in the interface:
#interface ivClientAppDelegate : NSObject <UIApplicationDelegate,ivAuthorizationProtocol
But then you would need to implement the methods in you main #implementation block.
Please note that by convention class and protocol names should start with an uppercase character.
Why don't you consider doing it like this:
#interface ivClientAppDelegate : NSObject <UIApplicationDelegate, ivAuthorizationProtocol >
Declaring protocol method as optional will fix the issue.
I need to be able to create an interface like you create in C# to enforce a group of classes to implement certain methods.
Is this possible in objective c?
You can create a protocol. it would look something like this:
in MyProtocol.h:
#protocol MyProtocol
-(void)myMethod;
-(void)myMethod2;
#end
in MyClass.h
#import "MyProtocol.h"
#interface MyClass : NSObject<MyProtocol>
#end
If you want to receive objects of a given protocol, you can do so like this:
id<MyProtocol> var;
or
NSObject<MyProtocol> *var;
more info here
You declare a "protocol" (Objective-C's interfaces) using
#protocol MyProtocol <BaseProtocol1,...,BaseProtocolN>
//methods and properties
#end
where <BaseProtocol> is optional and indicates that MyProtocol "inherits" BaseProtocol's interface. The NSObject protocol is useful in this context because it allows you to use
#protocol MyProtocol <NSObject>
//...
#end
to indicate (when appropriate) that conforming instances of MyProtocol have the standard NSObject methods as well (e.g. -retain/-release, etc.).
You then declare that a class "conforms" to a protocol:
#interface MyClass : NSObject <MyProtocol,...,OtherProtocols>
{}
#end
And you can test whether an instance conforms to a protocol:
id myInstance = ...; //some object instance
if([myInstance conformsToProtocol:#protocol(MyProtocol)]) {
// myInstance conforms to MyProtocol
}
You can further silence compiler warnings by declaring that a variable holds instances that conform to a protocol (note that Objective-C's dynamic nature prevents the compiler from verifying that contract and you can still get runtime errors by assigning a non-conforming instance to the variable):
id<MyProtocol> o;
In this case, the compiler will complain if you send [o retain] without MyProtocol conforming to the NSObject protocol. You can silence these warnings by declaring MyProtocol as conforming to NSObject as described above or by delcaring o as
NSObject<MyProtocol> o;
Since NSObject is not the only root object in Cocoa (i.e. NSProxy does not inherit from NSObject), it's not necessarily true that all instances conforming to MyProtocol also conform to NSObject. If you know that they do, you can declare MyProtocol as conforming to NSObject.
In the Objective-C world, interfaces are called "Protocols"
According to Apple,
Protocols declare methods that can be implemented by any class. Protocols are useful in at least three situations:
To declare methods that others are expected to implement
To declare the interface to an object while concealing its class
To capture similarities among classes that are not hierarchically related
So, to declare a protocol you can:
#protocol SomeClassProtocol
- (void) do:(int) number something:(id) sender;
- (void) somethingElse;
#end
To implement a protocol , you do:
#interface MyClass : NSObject <Protocol1, Protocol2, ..., ProtocolN>
#end
Check out this link for the official documentation.
Interfaces are called protocols in Objective C
If you go to add a class to your project you will have an option to create it as protocol and you will end up with something like:
#protocol MyProtocol
-(void) DoSomething;
#end