【发布时间】:2011-03-25 10:48:41
【问题描述】:
protocol 和 delegate 有什么区别?
和,
我们如何在protocol class 中声明variables?
【问题讨论】:
标签: ios objective-c delegates protocols
protocol 和 delegate 有什么区别?
和,
我们如何在protocol class 中声明variables?
【问题讨论】:
标签: ios objective-c delegates protocols
使用(Objective-C 中的@protocol 语法)声明的协议用于声明类“采用”(声明它将使用此协议)将实现的一组方法。这意味着您可以在代码中指定“只要它实现特定协议,您就不会关心使用哪个类”。这可以在 Objective-C 中按如下方式完成:
id<MyProtocol> instanceOfClassThatImplementsMyProtocol;
如果您在代码中声明了这一点,那么任何“符合”协议MyProtocol 的类都可以在变量instanceOfClassThatImplementsMyProtocol 中使用。这意味着使用这个变量的代码知道它可以使用 MyProtocol 中定义的任何方法和这个特定的变量,不管它是什么类。这是避免继承设计模式和避免紧耦合的好方法。
委托是对协议语言特性的一种使用。 delegation design pattern 是一种设计代码以在必要时使用协议的方法。在 Cocoa 框架中,委托设计模式用于指定符合特定协议的类的实例。这个特定的协议指定了委托类应该实现的方法,以在给定的事件中执行特定的操作。使用委托的类知道它的委托符合协议,因此它知道它可以在给定的时间调用实现的方法。这种设计模式是一种解耦类的好方法,因为它使得将一个委托实例交换为另一个委托实例变得非常容易——程序员所要做的就是确保替换的实例或类符合必要的协议(即它实现了协议中指定的方法)!
协议和委托不仅限于 Objective-C 和 Mac/iOS 开发,而且 Objective-C 语言和 Apple 框架也大量使用了这种令人敬畏的语言特性和设计模式。
编辑:
这是一个例子。在Cocoa Touch 的UIKit 框架中,有一个UITextFieldDelegate 协议。该协议定义了一系列方法,作为 UITextField 实例的委托的类应该实现这些方法。换句话说,如果你想给一个UITextField分配一个代理(使用delegate属性),你最好确保这个类符合UITextFieldDelegate。其实是因为UITextField的delegate属性定义为:
@property(nonatomic, weak) id<UITextFieldDelegate> delegate
如果你给它分配了一个没有实现协议的类,编译器会给出警告。这真的很有用。你必须声明一个类实现了一个协议,并且说它实现了,你让其他类知道它们可以以特定的方式与你的类交互。因此,如果您将 MyTextFieldDelegateClass 的实例分配给 UITextField 的 delegate 属性,则 UITextField 知道它可以调用您的MyTextFieldDelegateClass 的一些特定方法(与文本输入、选择等相关)。它知道这一点,因为 MyTextFieldDelegateClass 已经说过它将实现 UITextFieldDelegate 协议。
最终,这一切都会为您的项目代码带来更大的灵活性和适应性,我相信您在使用这项技术后很快就会意识到这一点! :)
【讨论】:
assign 应该是 weak 否则一旦代理被释放并在将来访问时它会崩溃。
协议是一组方法(可选或必需),将由符合该协议的类实现。而委托是对符合该协议的类的引用,并将遵守协议中定义的实现方法。
查看this Apple doc了解更多详情。
【讨论】:
委托:代表另一个对象行事(oops 中的设计模式)
这是一种设计模式,其中一个称为委托的对象代表另一个对象并应另一个对象的请求行事。在执行的某个时刻,它会向其委托发送消息;消息告诉代理一些事件即将发生并请求响应。代理实现消息调用的方法并返回适当的值
一个例子是appdelegate对象代表appobject。
协议:启用与继承无关的对象之间的通信
协议是编程接口的声明,其方法任何类都可以实现。协议是客观的 c 语言特性。简单地说,任何类都可以实现的方法列表。要使用它,您需要确认协议。 例如 UITableviewDatasource 协议,其方法 cellforRowAtIndexPath 在协议中声明,但我们实现它是为了创建 tableview。
【讨论】:
一个我重要的p先决条件是理解协议f首先然后委托。我建议你先看this 短教程,然后看What is a Protocol?。此外,您必须知道类和协议之间的区别,请参阅Objective-C: Class versus Protocol 和What is the point of Protocols?。
protocol: 只是要实现的功能的蓝图。任何采用该蓝图的类都必须实现这些功能。 (不要将实现函数与调用函数混淆)
delegate:1 是为了让你也做委托ing类正在做的事情没有 继承 例如
例如,您有一个 viewController 并且想要下载图像,或者您想要获取客户与商店的距离,因此您无需自己完成所有操作,而只需一个中等对象为您完成。该对象称为委托对象。通常你会这样做:
class ViewController : UIViewController , DownloaderDelegate{
//other code
// inside viewDidLoad or elsewhere you write:
downloaderHandler.delegate = self // now self can also use whatever the delegating object gives it...previously it was only a viewController but now it's 'almost' also a downloader
与您为符合 tableViewDelegate 所做的非常相似
class ViewController : UIViewController , UITableViewDelegate{
//other code
// inside viewDidLoad or elsewhere you write
tableView.delegate = self
你的 self 现在也可以做与 tableView 相关的事情了。
delegate:2
但是那个对象(委托)是一个普通的对象(id 或 Any)。太蠢了!你必须告诉它:“嘿,你必须努力拥有符合我们为你定义的协议所需的特定功能。(我们不会扩展 Any 或 id ,因为那会很愚蠢,(相反)我们制定了一个非常明确的受限协议“
在 Objective-C 中,它是纯粹的 id,所以你可以这样做
@property (weak) id<DownloaderProtocol>delegate;
在 Swift* 中你做起来稍微容易一些:
weak var delegate:DownloaderProtocol?
协议来拯救......委托实现(不使用)该功能,但它适合您的委托类的需求。
*:在 Swift 中,你没有 id,但你也不需要它的等价物 Any,因为在 Swift 中协议也是一等公民类型
【讨论】:
我们可以说协议是一组规则。 这些规则可以是可选的,也可以是必需的,就像我们必须在协议中使用一样。
Delegates 是 Objective C 和 swift 中的一种消息传递技术。一个对象必须处理该消息。
Ex: 一个每个iOS开发者习惯的简单例子就是UITableview,
创建表时,您必须在控制器中实现cellForRowAtIndexPath() 和numberOfRowsInSection(),根据需要在 UItableview 类中定义规则(协议),这是一个需要协议。
还有其他协议,例如heightForRowAtIndexPath(),是可选的。
现在来到 Delegate 在 UITableView 中有一个方法(消息)didSelectRowAtIndexPath() 向您发送事件消息。如果您将委托设置为 self 意味着您的控制器已准备好处理那个事件。
这个术语对开发者来说似乎更容易混淆,因为我们习惯于一起使用它(:
享受!!!!
【讨论】:
让我们看看程序中委托的声明
id<myProtocol> *delegatingObject;
delegatingObject 保持对另一个对象的引用,并在适当的时候向该对象发送消息。
协议是一组相关的属性和方法,可以由任何类实现。
这意味着任何确认 myProtocol(相关属性和方法组)的对象(id 类型)都可以作为代理工作,或者您可以说任何具有所需学位(协议)的人(id)都可以作为教师工作(代表)。
【讨论】:
委托和协议属于以下概念 (一对一)黑白视图控制器或类的通信模式。
这意味着一个类或 viewController 正在与另一个类或 viewController(点记一对一通信).m
第一类或 viewController 给(代表)它对第二类的引用
通过确认 2nd class 的协议,它正在与之交谈的 class。
使用 1st class 的 reference,2nd class 代表 1st 做工作 类,因此向第一类提供信息。
请使用以下链接观看该概念的实施: https://www.youtube.com/watch?v=DBWu6TnhLeY.
正式解释是 - 协议是一组方法(可选的或
必需的)将由(1st)类实现,这证实了这一点
协议。而委托是对确认的(第一个)类的引用
遵守该协议,并将遵守协议中定义的实现方法。
【讨论】: