【问题标题】:Obj-c, can I use a protocol as a type of parameter for function arguments?Obj-c,我可以将协议用作函数参数的一种参数吗?
【发布时间】:2019-03-19 07:53:51
【问题描述】:

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

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

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

我对使用协议很陌生。

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

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

如果没有怎么能做到这一点?

【问题讨论】:

  • 简单来说,您可以说我想将模型传递给框架内的类中的函数。我需要能够在我的应用程序中创建一个可以使用模型的类
  • 您在 iOS 和 AppKit 中找到的每个委托属性都是接受协议的方法的示例。示例:UITableView dataSource。这给出了方法setDataSource:(id<UITableViewDataSource>)delegate

标签: ios objective-c cocoa touch protocols


【解决方案1】:

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

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

@protocol Vehicle <NSObject>

@property NSNumber * numberOfWheels;

@required
-(void)engineOn;

@end

声明符合你的协议的类:

#import "Vehicle.h"

@interface Car : NSObject <Vehicle>

@end

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

@implementation Car
@synthesize numberOfWheels;

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

@end

还有一个,举个例子:

#import "Vehicle.h"

@interface Motorcycle : NSObject <Vehicle>

@end

@implementation Motorcycle
@synthesize numberOfWheels;

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

@end

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

#import "Vehicle.h"

@interface Race : NSObject

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

@end

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

@implementation Race

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

@end

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

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];

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

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

【讨论】:

  • 您能在协议中添加一些属性吗?
  • 肯定添加了。这很简单;只需在协议中声明属性,并确保在符合协议的类中合成它们(它们不会自动合成)。
  • 看起来不错,我想,我今天只想在接受之前实现这个。实际上,我将使用“车辆”之类的东西作为我的应用程序委托的协议,以将一些设置传递到我的框架中。我不想在框架之外定义我的应用程序委托属性的结构。听起来这一切都应该有效。
  • 公平地说,您的问题是关于如何使用协议作为方法的参数,而不是关于您的特定用例。也许至少要为努力投票?
  • 嗯,这是一个完全不同的问题,目前尚不清楚您要达到的目标(而且 cmets 并不是真正适合回答的地方)。最好的办法是尝试一下你的实现,然后在遇到一些具体问题时再问一个问题。接受与否完全取决于你,以后想接受也没问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多