764

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

但是我如何创建它们?

4

19 回答 19

914

Objective-C 委托是一个已分配给delegate另一个对象的属性的对象。要创建一个,您定义一个实现您感兴趣的委托方法的类,并将该类标记为实现委托协议。

例如,假设您有一个UIWebView. 如果你想实现它的委托webViewDidStartLoad:方法,你可以创建一个这样的类:

@interface MyClass<UIWebViewDelegate>
// ...
@end

@implementation MyClass
- (void)webViewDidStartLoad:(UIWebView *)webView { 
    // ... 
}
@end

然后您可以创建 MyClass 的实例并将其分配为 Web 视图的委托:

MyClass *instanceOfMyClass = [[MyClass alloc] init];
myWebView.delegate = instanceOfMyClass;

另一方面UIWebView,它可能具有与此类似的代码,以查看代理是否使用响应webViewDidStartLoad:消息respondsToSelector:并在适当时发送它。

if([self.delegate respondsToSelector:@selector(webViewDidStartLoad:)]) {
    [self.delegate webViewDidStartLoad:self];
}

委托属性本身通常被声明weak(在 ARC 中)或assign(在 ARC 之前)以避免保留循环,因为对象的委托通常持有对该对象的强引用。(例如,视图控制器通常是它包含的视图的委托。)

为您的课程安排代表

要定义您自己的委托,您必须在某处声明他们的方法,如Apple Docs on protocols中所讨论的那样。你通常声明一个正式的协议。从 UIWebView.h 解释的声明如下所示:

@protocol UIWebViewDelegate <NSObject>
@optional
- (void)webViewDidStartLoad:(UIWebView *)webView;
// ... other methods here
@end

这类似于接口或抽象基类,因为它为您的委托创建了一个特殊类型,UIWebViewDelegate在这种情况下。委托实现者必须采用这个协议:

@interface MyClass <UIWebViewDelegate>
// ...
@end

然后实现协议中的方法。对于在协议中声明为的方法@optional(像大多数委托方法一样),您需要-respondsToSelector:在调用特定方法之前检查 with 。

命名

委托方法通常以委托类名称开头,并将委托对象作为第一个参数。他们还经常使用 will-、should- 或 did- 形式。因此,webViewDidStartLoad:(第一个参数是 web 视图)而不是loadStarted(不带参数)例如。

速度优化

您可以在设置委托时缓存该信息,而不是每次我们想要发送消息时检查委托是否响应选择器。一种非常简洁的方法是使用位域,如下所示:

@protocol SomethingDelegate <NSObject>
@optional
- (void)something:(id)something didFinishLoadingItem:(id)item;
- (void)something:(id)something didFailWithError:(NSError *)error;
@end

@interface Something : NSObject
@property (nonatomic, weak) id <SomethingDelegate> delegate;
@end

@implementation Something {
  struct {
    unsigned int didFinishLoadingItem:1;
    unsigned int didFailWithError:1;
  } delegateRespondsTo;
}
@synthesize delegate;

- (void)setDelegate:(id <SomethingDelegate>)aDelegate {
  if (delegate != aDelegate) {
    delegate = aDelegate;

    delegateRespondsTo.didFinishLoadingItem = [delegate respondsToSelector:@selector(something:didFinishLoadingItem:)];
    delegateRespondsTo.didFailWithError = [delegate respondsToSelector:@selector(something:didFailWithError:)];
  }
}
@end

delegateRespondsTo然后,在正文中,我们可以通过访问我们的结构而不是-respondsToSelector:一遍又一遍地发送来检查我们的委托是否处理了消息。

非正式代表

在协议存在之前,通常使用一个类别NSObject声明委托可以实现的方法。例如,CALayer仍然这样做:

@interface NSObject(CALayerDelegate)
- (void)displayLayer:(CALayer *)layer;
// ... other methods here
@end

这告诉编译器任何对象都可以实现displayLayer:

然后,您将使用与上述相同的-respondsToSelector:方法来调用此方法。委托实现此方法并分配delegate属性,仅此而已(没有声明您符合协议)。这种方法在 Apple 的库中很常见,但是新代码应该使用上面更现代的协议方法,因为这种方法会造成污染NSObject(这会降低自动完成的用处)并使编译器很难警告您输入错误和类似错误。

于 2009-03-09T16:16:24.233 回答
395

批准的答案很棒,但如果您正在寻找 1 分钟的答案,请尝试以下操作:

MyClass.h 文件应如下所示(添加带注释的委托行!)

#import <BlaClass/BlaClass.h>

@class MyClass;             //define class, so protocol can see MyClass
@protocol MyClassDelegate <NSObject>   //define delegate protocol
    - (void) myClassDelegateMethod: (MyClass *) sender;  //define delegate method to be implemented within another class
@end //end protocol

@interface MyClass : NSObject {
}
@property (nonatomic, weak) id <MyClassDelegate> delegate; //define MyClassDelegate as delegate

@end

MyClass.m 文件应如下所示

#import "MyClass.h"
@implementation MyClass 
@synthesize delegate; //synthesise  MyClassDelegate delegate

- (void) myMethodToDoStuff {
    [self.delegate myClassDelegateMethod:self]; //this will call the method implemented in your other class    
}

@end

要在另一个类中使用您的委托(在本例中称为 MyVC 的 UIViewController)MyVC.h:

#import "MyClass.h"
@interface MyVC:UIViewController <MyClassDelegate> { //make it a delegate for MyClassDelegate
}

MyVC.m:

myClass.delegate = self;          //set its delegate to self somewhere

实现委托方法

- (void) myClassDelegateMethod: (MyClass *) sender {
    NSLog(@"Delegates are great!");
}
于 2012-09-30T10:25:40.570 回答
18

当使用正式的协议方法来创建委托支持时,我发现您可以通过添加以下内容来确保正确的类型检查(尽管是运行时,而不是编译时):

if (![delegate conformsToProtocol:@protocol(MyDelegate)]) {
    [NSException raise:@"MyDelegate Exception"
                format:@"Parameter does not conform to MyDelegate protocol at line %d", (int)__LINE__];
}

在您的委托访问器 (setDelegate) 代码中。这有助于减少错误。

于 2010-05-04T20:42:59.177 回答
17

也许这更符合您所缺少的内容:

如果您来自类似 C++ 的观点,代表需要一点时间来适应 - 但基本上“他们只是工作”。

它的工作方式是您将编写的一些对象设置为 NSWindow 的委托,但您的对象仅具有许多可能委托方法中的一种或几种的实现(方法)。所以发生了一些事情,并且NSWindow想要调用您的对象 - 它只是使用 Objective-c 的respondsToSelector方法来确定您的对象是否想要调用该方法,然后调用它。这就是objective-c的工作原理——方法是按需查找的。

用你自己的对象来做这件事完全是微不足道的,没有什么特别的事情发生,例如你可以有NSArray27 个对象,所有不同种类的对象,其中只有 18 个有方法-(void)setToBue;,其他 9 个没有。因此,要调用setToBlue所有需要完成的 18 个,如下所示:

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

关于委托的另一件事是它们不会被保留,因此您始终必须nilMyClass dealloc方法中将委托设置为。

于 2009-03-10T00:18:37.333 回答
17

请!查看下面的简单分步教程,了解 Delegates 在 iOS 中的工作原理。

iOS 中的委托

我创建了两个 ViewController(用于将数据从一个发送到另一个)

  1. FirstViewController 实现委托(提供数据)。
  2. SecondViewController 声明委托(它将接收数据)。
于 2013-02-27T12:21:24.460 回答
15

作为 Apple 推荐的一种良好做法,委托(根据定义,它是一种协议)符合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视图(符合您的委托)是否实际实现了您的可选方法。

于 2013-08-04T08:39:59.320 回答
11

我认为,一旦您了解了代表,所有这些答案都会很有意义。就我个人而言,我来自 C/C++ 领域,之前是 Fortran 等过程语言,所以这是我在 C++ 范式中寻找类似类似物的 2 分钟尝试。

如果我要向 C++/Java 程序员解释委托,我会说

什么是代表?这些是指向另一个类中的类的静态指针。分配指针后,您可以调用该类中的函数/方法。因此,您的类的某些功能被“委托”(在 C++ 世界中 - 类对象指针指向的指针)到另一个类。

什么是协议?从概念上讲,它的用途与您分配为委托类的类的头文件类似。协议是定义需要在类中实现哪些方法的显式方式,该类的指针被设置为类中的委托。

如何在 C++ 中做类似的事情?如果您尝试在 C++ 中执行此操作,您将通过在类定义中定义指向类(对象)的指针,然后将它们连接到其他类,这些类将提供附加功能作为基类的委托。但是这种接线需要在代码中维护,并且会很笨拙且容易出错。Objective C 只是假设程序员并不擅长维护这一原则,并提供编译器限制来强制执行干净的实现。

于 2013-06-19T10:34:42.990 回答
11

斯威夫特版本

委托只是一个为另一个类做一些工作的类。阅读下面的代码,了解一个有点愚蠢(但希望能带来启发)的 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!"
}

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

  1. 当一个班级需要向另一个班级传达一些信息时
  2. 当一个类想要允许另一个类自定义它时

除了委托类符合所需的协议外,这些类不需要事先了解彼此的任何信息。

我强烈推荐阅读以下两篇文章。他们帮助我比文档更好地理解了代表。

于 2015-11-05T17:11:08.413 回答
10

好的,这并不是问题的真正答案,但如果您正在寻找如何制作自己的代表,也许更简单的东西可能对您来说是一个更好的答案。

我几乎不执行我的代表,因为我很少需要。对于委托对象,我只能有一个委托。因此,如果您希望您的代表以一种方式进行通信/传递数据,那么您最好使用通知。

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];
}
于 2013-07-17T04:58:08.033 回答
8

假设您有一个您开发的类,并希望声明一个委托属性以便能够在某些事件发生时通知它:

@class myClass;

@protocol myClassDelegate <NSObject>

-(void)myClass:(MyClass*)myObject requiredEventHandlerWithParameter:(ParamType*)param;

@optional
-(void)myClass:(MyClass*)myObject optionalEventHandlerWithParameter:(ParamType*)param;

@end


@interface MyClass : NSObject

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

@end

所以你在MyClass头文件(或单独的头文件)中声明一个协议,并声明你的委托必须/应该实现的必需/​​可选事件处理程序,然后声明一个MyClass类型为 ( id< MyClassDelegate>) 的属性,这意味着任何符合的目标 c 类在协议MyClassDelegate中,您会注意到委托属性被声明为弱,这对于防止保留循环非常重要(通常委托保留MyClass实例,因此如果您将委托声明为保留,它们将相互保留并且两者都不会保留其中将永远被释放)。

您还会注意到协议方法将MyClass实例作为参数传递给委托,这是最好的做法,以防委托想要在实例上调用某些方法,MyClass并且当委托将自己声明为MyClassDelegate多个MyClass实例时也很有帮助,例如当您有多个实例时UITableView's你的实例,ViewController并声明自己为UITableViewDelegate所有实例。

在您的内部,您MyClass通过声明的事件通知委托,如下所示:

if([_delegate respondsToSelector:@selector(myClass: requiredEventHandlerWithParameter:)])
{
     [_delegate myClass:self requiredEventHandlerWithParameter:(ParamType*)param];
}

您首先检查您的委托是否响应您将要调用的协议方法,以防委托未实现它并且应用程序将崩溃(即使需要协议方法)。

于 2015-04-08T13:24:20.977 回答
7

要创建您自己的委托,首先您需要创建一个协议并声明必要的方法,而无需实现。然后将此协议实现到您想要实现委托或委托方法的头类中。

协议必须声明如下:

@protocol ServiceResponceDelegate <NSObject>

- (void) serviceDidFailWithRequestType:(NSString*)error;
- (void) serviceDidFinishedSucessfully:(NSString*)success;

@end

这是应该完成某些任务的服务类。它展示了如何定义委托以及如何设置委托。在任务完成后的实现类中,委托的方法被调用。

@interface ServiceClass : NSObject
{
id <ServiceResponceDelegate> _delegate;
}

- (void) setDelegate:(id)delegate;
- (void) someTask;

@end

@implementation ServiceClass

- (void) setDelegate:(id)delegate
{
_delegate = delegate;
}

- (void) someTask
{
/*

   perform task

*/
if (!success)
{
[_delegate serviceDidFailWithRequestType:@”task failed”];
}
else
{
[_delegate serviceDidFinishedSucessfully:@”task success”];
}
}
@end

这是通过将委托设置为自身来调用服务类的主视图类。并且该协议也在头类中实现。

@interface viewController: UIViewController <ServiceResponceDelegate>
{
ServiceClass* _service;
}

- (void) go;

@end

@implementation viewController

//
//some methods
//

- (void) go
{
_service = [[ServiceClass alloc] init];
[_service setDelegate:self];
[_service someTask];
}

就是这样,通过在这个类中实现委托方法,一旦操作/任务完成,控制权就会回来。

于 2015-08-03T04:47:04.140 回答
6

这是创建委托的简单方法

在 .h 文件中创建协议。确保在协议之前使用 @class 定义,后跟 UIViewController 的名称< As the protocol I am going to use is UIViewController class>.

步骤: 1:创建一个名为“YourViewController”的新类协议,它将作为 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 作为协议定义的一部分来控制。

Step : 3 : Delegate 的实现

    #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]; 
     }
  }
于 2015-09-29T09:23:09.937 回答
5

免责声明:这是Swift如何创建delegate.

那么,什么是代表?......在软件开发中,有通用的可重用解决方案架构有助于解决给定上下文中常见的问题,可以说,这些“模板”最为人所知的是设计模式。委托是一种设计模式,它允许一个对象在特定事件发生时向另一个对象发送消息。想象一个对象 A 调用一个对象 B 来执行一个动作。一旦动作完成,对象 A 应该知道 B 已经完成了任务并采取必要的动作,这可以在委托的帮助下实现!

为了更好地解释,我将向您展示如何创建一个在类之间传递数据的自定义委托,在一个简单的应用程序中使用 Swift,首先下载或克隆这个启动项目并运行它!

您可以看到一个包含两个类的应用程序,ViewController A并且ViewController B. B 有两个视图,可以在点击时更改背景颜色ViewController,没什么太复杂的吧?好吧,现在让我们以一种简单的方式思考,当点击 B 类的视图时,也可以改变 A 类的背景颜色。

问题是这个视图是 B 类的一部分,不知道 A 类,所以我们需要找到一种方法在这两个类之间进行通信,这就是委托的亮点。我将实现分为 6 个步骤,因此您可以在需要时将其用作备忘单。

第 1 步:在 ClassBVC 文件中查找编译指示标记第 1 步并添加此

//MARK: step 1 Add Protocol here.
protocol ClassBVCDelegate: class {
func changeBackgroundColor(_ color: UIColor?)
}

第一步是创建一个protocol,在这种情况下,我们将在 B 类中创建协议,在协议中,您可以根据实现的要求创建任意数量的函数。在这种情况下,我们只有一个简单的函数,它接受一个可选UIColor参数作为参数。delegate在类名末尾添加单词来命名协议是一个好习惯,在这种情况下, ClassBVCDelegate.

第 2 步:在第 2 步中查找编译指示标记ClassVBC并添加此

//MARK: step 2 Create a delegate property here.
weak var delegate: ClassBVCDelegate?

这里我们只是为类创建了一个委托属性,这个属性必须采用protocol类型,并且应该是可选的。另外,你应该在属性之前添加weak关键字以避免保留循环和潜在的内存泄漏,如果你不知道这意味着什么现在不要担心,只要记住添加这个关键字。

第3步:在handleTapmethod中查找pragma mark step 3ClassBVC并添加

//MARK: step 3 Add the delegate method call here.
delegate?.changeBackgroundColor(tapGesture.view?.backgroundColor)

您应该知道的一件事是,运行应用程序并点击任何视图,您不会看到任何新行为,这是正确的,但我想指出的是,当调用委托时应用程序不会崩溃,并且这是因为我们将它创建为一个可选值,这就是为什么即使委托不存在它也不会崩溃的原因。现在让我们去ClassAVC归档并制作它,委托人。

第 4 步:在 handleTap 方法中查找编译指示第 4 步,ClassAVC并将其添加到您的类类型旁边,如下所示。

//MARK: step 4 conform the protocol here.
class ClassAVC: UIViewController, ClassBVCDelegate {
}

现在 ClassAVC 采用了ClassBVCDelegate协议,你可以看到你的编译器给你一个错误,说“Type 'ClassAVC does not conform to protocol 'ClassBVCDelegate' 这只是意味着你还没有使用协议的方法,想象一下当 A 类采用协议时,就像与 B 类签订合同,并且该合同说“任何采用我的类都必须使用我的功能!”</p>

快速说明:如果您有Objective-C背景,您可能会认为您也可以关闭该错误,使该方法成为可选方法,但令我惊讶的是,可能是您的,Swift语言不支持 optional protocols,如果您想这样做,您可以创建您的扩展或在您的实现protocol中使用 @objc 关键字。protocol

就个人而言,如果我必须创建具有不同可选方法的协议,我更愿意将其分解为不同protocols的 ,这样我将遵循为我的对象赋予单一职责的概念,但它可能会根据具体实现而有所不同。

这是一篇关于可选方法的好文章。

第5步:在prepare for segue方法中寻找pragma mark step 5并添加这个

//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 就是ClassAVC被委派的那个!

第 6 步:最后,查找第 6 步中的 pragma ClassAVC,让我们使用 的功能protocol,开始输入 func changeBackgroundColor,您会看到它会自动为您完成。您可以在其中添加任何实现,在此示例中,我们将仅更改背景颜色,添加它。

//MARK: step 6 finally use the method of the contract
func changeBackgroundColor(_ color: UIColor?) {
view.backgroundColor = color
}

现在运行应用程序!

Delegates无处不在,你可能会在没有通知的情况下使用它们,如果你tableview在过去创建了一个你使用过的委托,UIKIT围绕它们的许多类的作品以及许多其他的作品frameworks,它们解决了这些主要问题。

  • 避免对象的紧密耦合。
  • 无需子类化对象即可修改行为和外观。
  • 允许将任务处理到任何任意对象。

恭喜你,你刚刚实现了一个自定义委托,我知道你可能在想,就为了这个这么麻烦?好吧,如果您想成为一名iOS开发人员,委托是一种非常重要的设计模式,并且始终牢记它们在对象之间具有一对一的关系。

您可以在此处查看原始教程

于 2017-04-26T05:27:43.480 回答
5

答案实际上已经回答,但我想给你一个“备忘单”来创建一个代表:

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
于 2018-03-16T04:40:48.620 回答
2

视图控制器.h

@protocol NameDelegate <NSObject>

-(void)delegateMEthod: (ArgType) arg;

@end

@property id <NameDelegate> delegate;

视图控制器.m

[self.delegate delegateMEthod: argument];

主视图控制器.m

ViewController viewController = [ViewController new];
viewController.delegate = self;

方法:

-(void)delegateMEthod: (ArgType) arg{
}
于 2016-12-19T04:14:58.487 回答
2

在我看来,为该委托方法创建单独的类,您可以在需要的地方使用。

在我的自定义 DropDownClass.h

typedef enum
{
 DDSTATE,
 DDCITY
}DropDownType;

@protocol DropDownListDelegate <NSObject>
@required
- (void)dropDownDidSelectItemWithString:(NSString*)itemString     DropDownType:(DropDownType)dropDownType;
@end
@interface DropDownViewController : UIViewController
{
 BOOL isFiltered;
}
@property (nonatomic, assign) DropDownType dropDownType;
@property (weak) id <DropDownListDelegate> delegate;
@property (strong, nonatomic) NSMutableArray *array1DropDown;
@property (strong, nonatomic) NSMutableArray *array2DropDown;

在那之后 in.m 文件创建带有对象的数组,

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
CGFloat rowHeight = 44.0f;
return rowHeight;
}

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return isFiltered?[self.array1DropDown count]:[self.array2DropDown count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = @"TableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}

if (self.delegate) {
    if (self.dropDownType == DDCITY) {
        cell.textLabel.text = [self.array1DropDown objectAtIndex:indexPath.row];
    }
    else if (self.dropDownType == DDSTATE) {
        cell.textLabel.text = [self.array2DropDown objectAtIndex:indexPath.row];
    }
}
return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
 [self dismissViewControllerAnimated:YES completion:^{
    if(self.delegate){
        if(self.dropDownType == DDCITY){
            [self.delegate dropDownDidSelectItemWithString:[self.array1DropDown objectAtIndex:indexPath.row] DropDownType:self.dropDownType];
        }
        else if (self.dropDownType == DDSTATE) {
            [self.delegate dropDownDidSelectItemWithString:[self.array2DropDown objectAtIndex:indexPath.row] DropDownType:self.dropDownType];
        }
    }
}];
}

这里所有的都是为自定义委托类设置的。之后你可以在你想要的地方使用这个委托方法。例如...

在我的另一个视图控制器导入之后

像这样创建调用委托方法的动作

- (IBAction)dropDownBtn1Action:(id)sender {
DropDownViewController *vehicleModelDropView = [[DropDownViewController alloc]init];
vehicleModelDropView.dropDownType = DDCITY;
vehicleModelDropView.delegate = self;
[self presentViewController:vehicleModelDropView animated:YES completion:nil];
}

之后像这样调用委托方法

- (void)dropDownDidSelectItemWithString:(NSString *)itemString DropDownType:(DropDownType)dropDownType {
switch (dropDownType) {
    case DDCITY:{
        if(itemString.length > 0){
            //Here i am printing the selected row
            [self.dropDownBtn1 setTitle:itemString forState:UIControlStateNormal];
        }
    }
        break;
    case DDSTATE: {
        //Here i am printing the selected row
        [self.dropDownBtn2 setTitle:itemString forState:UIControlStateNormal];
    }

    default:
        break;
}
}
于 2017-02-08T09:30:59.663 回答
0

代表:- 创建

@protocol addToCartDelegate <NSObject>

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

@end

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

[self.delegate addToCartAction:itemsModel isAdded:YES];
于 2016-12-08T10:50:58.783 回答
0
//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)tag { NSLog@("Tag %d",tag);

}

于 2017-01-02T16:31:44.540 回答
0

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

因此,如果我们从应用程序的角度考虑,一个活动可以是一个在线订单,而不同的团队可以是多个视图。

这是将 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
        //
    }
}
于 2017-07-14T10:14:49.340 回答