Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Obj-c, can I use a protocol as a type of parameter for function arguments?

I’m create a cocoa touch framework to share some common code between my apps.

I need to pass an instance of a class into a method, which has some specific properties.

The method will be called from the app.

I’m quite new to using protocols.

Should I create a protocol h file in my framework with all the properties required by the function.

If so can I pass the protocol as the type of the instance variable into the function?

If not how can achieve this?

like image 256
Jules Avatar asked Oct 14 '18 21:10

Jules


Video Answer


1 Answers

Yes, you can. Here's an example.

First, declare your protocol in a .h file:

@protocol Vehicle <NSObject>

@property NSNumber * numberOfWheels;

@required
-(void)engineOn;

@end

Declare the classes which conform to your protocol:

#import "Vehicle.h"

@interface Car : NSObject <Vehicle>

@end

Implement the required methods and synthesise the properties:

@implementation Car
@synthesize numberOfWheels;

-(void)engineOn {
    NSLog(@"Car engine on");
}

@end

and another, for the sake of example:

#import "Vehicle.h"

@interface Motorcycle : NSObject <Vehicle>

@end

@implementation Motorcycle
@synthesize numberOfWheels;

-(void)engineOn {
    NSLog(@"Motorcycle engine on");
}

@end

When you declare a method which you want to accept a Vehicle argument, you use the generic id type and specify that any object passed in should conform to Vehicle:

#import "Vehicle.h"

@interface Race : NSObject

-(void)addVehicleToRace:(id<Vehicle>)vehicle;

@end

Then, in the implementation for that method, you can use the properties and methods declared in the protocol, regardless of the concrete type that has been passed in:

@implementation Race

-(void)addVehicleToRace:(id<Vehicle>)vehicle {
    [vehicle engineOn];
}

@end

Then, as you'd expect, you can pass in instances of concrete classes that conform to your protocol:

Motorcycle *cycle = [[Motorcycle alloc] init];
cycle.numberOfWheels = 2;
Car *car = [[Car alloc] init];
car.numberOfWheels = 4;
Race *race = [[Race alloc] init];
[race addVehicleToRace:car];
[race addVehicleToRace:cycle];

And the appropriate concrete implementation of the protocol's methods will be executed, depending on the actual concrete types that you pass as a parameter:

2018-10-15 13:53:45.039596+0800 ProtocolExample[78912:1847146] Car engine on
2018-10-15 13:53:45.039783+0800 ProtocolExample[78912:1847146] Motorcycle engine on
like image 98
Pete Morris Avatar answered Sep 28 '22 01:09

Pete Morris