Obj-c,我可以使用协议作为函数参数的参数类型吗?

Jul*_*les 5 cocoa protocols objective-c touch ios

我正在创建一个可可触摸框架来在我的应用程序之间共享一些通用代码。

我需要将一个类的实例传递给一个方法,该方法具有一些特定的属性。

该方法将从应用程序中调用。

我对使用协议很陌生。

我是否应该在我的框架中创建一个协议 h 文件,其中包含该函数所需的所有属性。

如果是这样,我可以将协议作为实例变量的类型传递给函数吗?

如果不是怎么能做到这一点?

Pet*_*ris 6

是的你可以。这是一个例子。

首先,在.h文件中声明您的协议:

@protocol Vehicle <NSObject>

@property NSNumber * numberOfWheels;

@required
-(void)engineOn;

@end
Run Code Online (Sandbox Code Playgroud)

声明符合您的协议的类:

#import "Vehicle.h"

@interface Car : NSObject <Vehicle>

@end
Run Code Online (Sandbox Code Playgroud)

实现所需的方法并综合属性:

@implementation Car
@synthesize numberOfWheels;

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

@end
Run Code Online (Sandbox Code Playgroud)

另一个,例如:

#import "Vehicle.h"

@interface Motorcycle : NSObject <Vehicle>

@end

@implementation Motorcycle
@synthesize numberOfWheels;

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

@end
Run Code Online (Sandbox Code Playgroud)

当你声明一个你想要接受Vehicle参数的方法时,你使用泛型id类型并指定传入的任何对象都应该符合Vehicle

#import "Vehicle.h"

@interface Race : NSObject

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

@end
Run Code Online (Sandbox Code Playgroud)

然后,在该方法的实现中,您可以使用协议中声明的属性和方法,而不管传入的具体类型如何:

@implementation Race

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

@end
Run Code Online (Sandbox Code Playgroud)

然后,如您所料,您可以传入符合您的协议的具体类的实例:

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];
Run Code Online (Sandbox Code Playgroud)

并且将执行协议方法的适当具体实现,具体取决于您作为参数传递的实际具体类型:

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
Run Code Online (Sandbox Code Playgroud)