我知道委托是如何工作的,也知道如何使用它们。

但是我如何创建它们呢?


当前回答

这并不是问题的答案,但如果你在查找如何创建自己的委托也许一些更简单的东西会是更好的答案。

我很少实现委托,因为我很少需要。对于一个委托对象,我只能有一个委托。所以如果你想让你的委托进行单向通信/传递数据,你最好使用通知。

NSNotification可以将对象传递给多个接收者,它非常容易使用。 它是这样工作的:

MyClass。M文件应该是这样的

#import "MyClass.h"
@implementation MyClass 

- (void) myMethodToDoStuff {
//this will post a notification with myClassData (NSArray in this case)  in its userInfo dict and self as an object
[[NSNotificationCenter defaultCenter] postNotificationName:@"myClassUpdatedData"
                                                    object:self
                                                  userInfo:[NSDictionary dictionaryWithObject:selectedLocation[@"myClassData"] forKey:@"myClassData"]];
}
@end

在其他类中使用通知: 添加类作为观察者:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(otherClassUpdatedItsData:) name:@"myClassUpdatedData" object:nil];

实现选择器:

- (void) otherClassUpdatedItsData:(NSNotification *)note {
    NSLog(@"*** Other class updated its data ***");
    MyClass *otherClass = [note object];  //the object itself, you can call back any selector if you want
    NSArray *otherClassData = [note userInfo][@"myClassData"]; //get myClass data object and do whatever you want with it
}

如果,不要忘记删除你的类作为观察者

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

其他回答

答案实际上已经回答了,但我想给你一个创建委托的“小抄”:

DELEGATE SCRIPT

CLASS A - Where delegate is calling function

@protocol <#Protocol Name#> <NSObject>

-(void)delegateMethod;

@end

@interface <#Some ViewController#> : <#UIViewController#> 

@property (nonatomic, assign) id <<#Protocol Name#>> delegate;

@end


@implementation <#Some ViewController#> 

-(void)someMethod {
    [self.delegate methodName];
}

@end




CLASS B - Where delegate is called 

@interface <#Other ViewController#> (<#Delegate Name#>) {}
@end

@implementation <#Other ViewController#> 

-(void)otherMethod {
    CLASSA *classA = [[CLASSA alloc] init];

    [classA setDelegate:self];
}

-delegateMethod() {

}

@end

我认为一旦你理解了委托,所有这些答案都很有意义。就我个人而言,我来自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.

让我们从一个例子开始,如果我们在网上购买一件产品,它会经过不同团队处理的运输/交付等流程。因此,如果运输完成,运输团队应该通知交付团队,并且应该是一对一的沟通,因为广播这个信息对其他人来说是一种开销/供应商可能只希望将这个信息传递给需要的人。

所以如果我们从应用的角度考虑,一个事件可以是一个在线订单,不同的团队可以是多个视图。

下面是代码,将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
        //
    }
}

下面是一个创建委托的简单方法

在.h文件中创建协议。确保它是在协议之前定义的,使用@class后面跟着UIViewController的名字,因为我要使用的协议是UIViewController类>。

步骤:1:创建一个名为“YourViewController”的新类Protocol,它将是UIViewController类的子类,并将这个类分配给第二个ViewController。

步骤2:转到“YourViewController”文件,并如下所示修改它:

#import <UIKit/UIkit.h>
@class YourViewController;

@protocol YourViewController Delegate <NSObject>

 @optional
-(void)defineDelegateMethodName: (YourViewController *) controller;

@required
-(BOOL)delegateMethodReturningBool: (YourViewController *) controller;

  @end
  @interface YourViewController : UIViewController

  //Since the property for the protocol could be of any class, then it will be marked as a type of id.

  @property (nonatomic, weak) id< YourViewController Delegate> delegate;

@end

协议行为中定义的方法可以用@optional和@required作为协议定义的一部分进行控制。

步骤3: 委托的实现

    #import "delegate.h"

   @interface YourDelegateUser ()
     <YourViewControllerDelegate>
   @end

   @implementation YourDelegateUser

   - (void) variousFoo {
      YourViewController *controller = [[YourViewController alloc] init];
      controller.delegate = self;
   }

   -(void)defineDelegateMethodName: (YourViewController *) controller {
      // handle the delegate being called here
   }

   -(BOOL)delegateMethodReturningBool: (YourViewController *) controller {
      // handle the delegate being called here
      return YES;
   }

   @end

//在调用该方法之前测试该方法是否已经定义

 - (void) someMethodToCallDelegate {
     if ([[self delegate] respondsToSelector:@selector(defineDelegateMethodName:)]) {
           [self.delegate delegateMethodName:self]; 
     }
  }

一张图片胜过千言万语:-P

Objective-C代码的函数主体中的变量迎宾器被称为委托,它只不过是一个c++指针,指向实现纯虚函数类的对象。