我知道委托是如何工作的,也知道如何使用它们。
但是我如何创建它们呢?
我知道委托是如何工作的,也知道如何使用它们。
但是我如何创建它们呢?
当前回答
让我们从一个例子开始,如果我们在网上购买一件产品,它会经过不同团队处理的运输/交付等流程。因此,如果运输完成,运输团队应该通知交付团队,并且应该是一对一的沟通,因为广播这个信息对其他人来说是一种开销/供应商可能只希望将这个信息传递给需要的人。
所以如果我们从应用的角度考虑,一个事件可以是一个在线订单,不同的团队可以是多个视图。
下面是代码,将ShippingView作为发货团队,将DeliveryView作为交付团队:
//Declare the protocol with functions having info which needs to be communicated
protocol ShippingDelegate : class {
func productShipped(productID : String)
}
//shippingView which shows shipping status of products
class ShippingView : UIView
{
weak var delegate:ShippingDelegate?
var productID : String
@IBAction func checkShippingStatus(sender: UIButton)
{
// if product is shipped
delegate?.productShipped(productID: productID)
}
}
//Delivery view which shows delivery status & tracking info
class DeliveryView: UIView,ShippingDelegate
{
func productShipped(productID : String)
{
// update status on view & perform delivery
}
}
//Main page on app which has both views & shows updated info on product whole status
class ProductViewController : UIViewController
{
var shippingView : ShippingView
var deliveryView : DeliveryView
override func viewDidLoad() {
super.viewDidLoad()
// as we want to update shipping info on delivery view, so assign delegate to delivery object
// whenever shipping status gets updated it will call productShipped method in DeliveryView & update UI.
shippingView.delegate = deliveryView
//
}
}
其他回答
一张图片胜过千言万语:-P
Objective-C代码的函数主体中的变量迎宾器被称为委托,它只不过是一个c++指针,指向实现纯虚函数类的对象。
//1.
//Custom delegate
@protocol TB_RemovedUserCellTag <NSObject>
-(void)didRemoveCellWithTag:(NSInteger)tag;
@end
//2.
//Create a weak reference in a class where you declared the delegate
@property(weak,nonatomic)id <TB_RemovedUserCellTag> removedCellTagDelegate;
//3.
// use it in the class
[self.removedCellTagDelegate didRemoveCellWithTag:self.tag];
//4. import the header file in the class where you want to conform to the protocol
@interface MyClassUsesDelegate ()<TB_RemovedUserCellTag>
@end
/ / 5。在类.m中实现该方法 - (void) didRemoveCellWithTag: (NSInteger)标记 { NSLog@(“% d”标签,标签);
}
我认为一旦你理解了委托,所有这些答案都很有意义。就我个人而言,我来自C/ c++的土地,在此之前,像Fortran等过程语言,所以这里是我在c++范式中寻找类似类似物的2分钟。
如果我要向c++ /Java程序员解释委托,我会说
什么是委托? 这些是指向另一个类中的类的静态指针。一旦你分配了一个指针,你就可以调用该类中的函数/方法。因此,类的一些函数被“委托”(在c++中,由类对象指针指向的指针)给另一个类。
什么是协议? 从概念上讲,它的作用与你作为委托类分配的类的头文件类似。协议是一种显式的方式,用于定义在类中需要实现哪些方法,而该类的指针被设置为类中的委托。
How can I do something similar in C++? If you tried to do this in C++, you would by defining pointers to classes (objects) in the class definition and then wiring them up to other classes that will provide additional functions as delegates to your base class. But this wiring needs to be maitained within the code and will be clumsy and error prone. Objective C just assumes that programmers are not best at maintaining this decipline and provides compiler restrictions to enforce a clean implementation.
委托:-创建
@protocol addToCartDelegate <NSObject>
-(void)addToCartAction:(ItemsModel *)itemsModel isAdded:(BOOL)added;
@end
发送并请指定代表查看您正在发送的数据
[self.delegate addToCartAction:itemsModel isAdded:YES];
免责声明:这是如何创建委托的Swift版本。
So, what are delegates? …in software development, there are general reusable solution architectures that help to solve commonly occurring problems within a given context, these “templates”, so to speak, are best known as design patterns. Delegates are a design pattern that allows one object to send messages to another object when a specific event happens. Imagine an object A calls an object B to perform an action. Once the action is complete, object A should know that B has completed the task and take necessary action, this can be achieved with the help of delegates!
为了更好的解释,我将向你展示如何在一个简单的应用程序中创建一个自定义委托,在类之间传递数据,首先下载或克隆这个starter项目并运行它!
你可以看到一个应用有两个类,ViewController A和ViewController B, B有两个视图在点击时改变ViewController的背景颜色,没什么太复杂的对吧?好,现在让我们用一种简单的方法来思考,当类B的视图被点击时,也改变类A的背景颜色。
问题是,这个视图是类B的一部分,对类A一无所知,所以我们需要找到一种方法在这两个类之间进行通信,这就是委派的作用所在。 我将实现分为6个步骤,以便在需要时将其作为备忘单使用。
步骤1:在ClassBVC文件中寻找步骤1的pragma标记并添加这个
//MARK: step 1 Add Protocol here.
protocol ClassBVCDelegate: class {
func changeBackgroundColor(_ color: UIColor?)
}
第一步是创建一个协议,在这种情况下,我们将在类B中创建协议,在协议中,您可以根据实现的需求创建尽可能多的函数。在本例中,我们只有一个简单的函数,它接受一个可选的UIColor作为参数。 在类名的末尾添加单词delegate来命名协议是一个很好的做法,在本例中是ClassBVCDelegate。
步骤2:在ClassVBC中寻找步骤2的pragma标记并添加这个
//MARK: step 2 Create a delegate property here.
weak var delegate: ClassBVCDelegate?
这里我们只是为类创建了一个委托属性,这个属性必须采用协议类型,并且它应该是可选的。此外,您应该在属性之前添加weak关键字,以避免保留周期和潜在的内存泄漏,如果您不知道这意味着什么,现在不用担心,只需要记住添加这个关键字。
步骤3:在ClassBVC的handleTap方法中寻找步骤3中的pragma标记并添加它
//MARK: step 3 Add the delegate method call here.
delegate?.changeBackgroundColor(tapGesture.view?.backgroundColor)
你需要知道的是,运行应用,点击任意视图,你不会看到任何新行为,这是对的但我想指出的是,应用在调用委托时不会崩溃,这是因为我们将它创建为可选值这就是它不会崩溃的原因即使委托还不存在。现在我们转到ClassAVC文件,把它变成委托的。
第四步:在ClassAVC的handleTap方法中寻找第四步的pragma标记,并像这样将其添加到您的类类型旁边。
//MARK: step 4 conform the protocol here.
class ClassAVC: UIViewController, ClassBVCDelegate {
}
现在ClassAVC采用了ClassBVCDelegate协议,你可以看到你的编译器给你一个错误,说“类型' ClassAVC不符合协议' ClassBVCDelegate ',这只意味着你还没有使用协议的方法,想象一下,当类A采用协议时,就像与类B签署了一个合同,这个合同说“任何采用我的类必须使用我的函数!”
注意:如果你有Objective-C背景,你可能会想,你也可以关闭这个错误,使这个方法是可选的,但令我惊讶的是,Swift语言不支持可选协议,如果你想这样做,你可以为你的协议创建一个扩展,或者在你的协议实现中使用@objc关键字。
就我个人而言,如果我必须创建一个具有不同可选方法的协议,我更喜欢将其分解为不同的协议,这样我将遵循给我的对象一个单一责任的概念,但它可以根据具体的实现而变化。
这是一篇关于可选方法的好文章。
步骤5:在prepareforsegue方法中寻找步骤5的pragma标记,并添加这个
//MARK: step 5 create a reference of Class B and bind them through the `prepareforsegue` method.
if let nav = segue.destination as? UINavigationController, let classBVC = nav.topViewController as? ClassBVC {
classBVC.delegate = self
}
这里我们只是创建了ClassBVC的一个实例并将它的委托分配给self, self是什么呢?self是被委派的类avc !
第六步:最后,在ClassAVC中寻找pragma第六步,让我们使用协议的函数,开始输入func changeBackgroundColor,你会看到它为你自动完成它。你可以在里面添加任何实现,在这个例子中,我们只需要改变背景颜色,添加这个。
//MARK: step 6 finally use the method of the contract
func changeBackgroundColor(_ color: UIColor?) {
view.backgroundColor = color
}
现在运行应用程序!
委托无处不在,你可能会无意识地使用它们,如果你过去创建一个表视图,你使用委托,UIKIT的很多类都围绕着它们工作,很多其他框架也一样,它们解决了这些主要问题。
避免对象的紧密耦合。 修改行为和外观而不需要子类化对象。 允许任务被处理到任何任意对象。
恭喜你,你实现了一个自定义委托,我知道你可能在想,这么麻烦?如果你想成为一名iOS开发者,委托是一个非常重要的设计模式,要记住它们在对象之间是一对一的关系。
你可以在这里看到原始教程