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

但是我如何创建它们呢?


当前回答

也许这更符合你所错过的:

如果你从c++的角度来看,委托需要一点时间来适应——但基本上“它们就是工作”。

它的工作方式是,你设置一些对象,你写的委托到NSWindow,但你的对象只有实现(方法)为一个或几个可能的委托方法。发生了一些事情,NSWindow想要调用你的对象它使用Objective-c的respondsToSelector方法来确定你的对象是否想要调用那个方法,然后调用它。这就是objective-c的工作方式——根据需要查找方法。

对你自己的对象做这个完全是微不足道的,没有什么特别的,例如,你可以有一个包含27个对象的NSArray,所有不同类型的对象,只有18个其中一些有方法-(void)setToBue;其他9个没有。在所有18个需要执行的地方调用setToBlue,就像这样:

for (id anObject in myArray)
{
  if ([anObject respondsToSelector:@selector(@"setToBlue")])
     [anObject setToBlue]; 
}

关于委托的另一件事是它们不会被保留,所以你总是需要在MyClass dealloc方法中将委托设为nil。

其他回答

作为苹果公司推荐的一个好的实践,委托(根据定义,它是一个协议)符合NSObject协议是有好处的。

@protocol MyDelegate <NSObject>
    ...
@end

要在你的委托中创建可选方法(即不一定要实现的方法),你可以像这样使用@optional注释:

@protocol MyDelegate <NSObject>
    ...
    ...
      // Declaration for Methods that 'must' be implemented'
    ...
    ...
    @optional
    ...
      // Declaration for Methods that 'need not necessarily' be implemented by the class conforming to your delegate
    ...
@end

因此,当使用你指定为可选的方法时,你需要(在你的类中)检查respondsToSelector是否视图(符合你的委托)已经实际实现了你的可选方法。

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

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

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

委托:-创建

@protocol addToCartDelegate <NSObject>

-(void)addToCartAction:(ItemsModel *)itemsModel isAdded:(BOOL)added;

@end

发送并请指定代表查看您正在发送的数据

[self.delegate addToCartAction:itemsModel isAdded:YES];

斯威夫特版本

委托只是一个为另一个类做一些工作的类。阅读下面的代码,这是一个有点傻(但希望有启发性)的Playground示例,它展示了如何在Swift中实现这一点。

// A protocol is just a list of methods (and/or properties) that must
// be used by any class that adopts the protocol.
protocol OlderSiblingDelegate: class {
    // This protocol only defines one required method
    func getYourNiceOlderSiblingAGlassOfWater() -> String
}

class BossyBigBrother {
    
    // The delegate is the BossyBigBrother's slave. This position can 
    // be assigned later to whoever is available (and conforms to the 
    // protocol).
    weak var delegate: OlderSiblingDelegate?
    
    func tellSomebodyToGetMeSomeWater() -> String? {
        // The delegate is optional because there might not be anyone
        // nearby to boss around.
        return delegate?.getYourNiceOlderSiblingAGlassOfWater()
    }
}

// PoorLittleSister conforms to the OlderSiblingDelegate protocol
class PoorLittleSister: OlderSiblingDelegate {

    // This method is repquired by the protocol, but the protocol said
    // nothing about how it needs to be implemented.
    func getYourNiceOlderSiblingAGlassOfWater() -> String {
        return "Go get it yourself!"
    }
    
}

// initialize the classes
let bigBro = BossyBigBrother()
let lilSis = PoorLittleSister()

// Set the delegate 
// bigBro could boss around anyone who conforms to the 
// OlderSiblingDelegate protocol, but since lilSis is here, 
// she is the unlucky choice.
bigBro.delegate = lilSis

// Because the delegate is set, there is a class to do bigBro's work for him.
// bigBro tells lilSis to get him some water.
if let replyFromLilSis = bigBro.tellSomebodyToGetMeSomeWater() {
    print(replyFromLilSis) // "Go get it yourself!"
}

在实际实践中,委托通常用于以下情况

当一个类需要向另一个类传递一些信息时 当一个类希望允许另一个类自定义它时

类之间不需要事先知道彼此的任何信息,除非委托类符合所需的协议。

我强烈推荐阅读以下两篇文章。它们甚至比文档更能帮助我理解委托。

什么是委托?-快速开发人员指南 委托如何工作-一个快速的开发者指南

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

在.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]; 
     }
  }