iOS开发-委托(Delegate)浅谈

十度 IOS 2015年12月01日 收藏

委托其实并不是OC中才有,C#中也有,不过彼此的理解方式是不一样的,OC中委托是协议的一种,需要使用@protocol声明,委托一般在iOS开发中页面中传值用的比较多。委托是Cocoa中最简单、最灵活的模式之一,委托其实字面上的意思就是将需要的事情委托给别人做,业务场景可以参考主视图和子视图之间的页面关系,或者是视图层和数据层之间的交互。

简单的委托

委托通过@protocol声明,可以定义方法,引用委托的对象,需要实现其方法,方法默认都是@required的,同时可以设置为可选的@optional,首先定义个委托:

  1. @protocol BookDelegate <NSObject>
  2. @required
  3. - (void)getBookCount;
  4. @optional
  5. - (void)optionMethod;
  6.  
  7. @end

 这个时候定义书籍Book类和客户Customer类:

  1. @interface Book : NSObject<BookDelegate>
  2.  
  3. @end
  4.  
  5. @interface Customer : NSObject<BookDelegate>
  6.  
  7. @property (assign,nonatomic) id<BookDelegate> didBookDelegate;
  8.  
  9. @end

 实现其中的getBookCount方法:

  1. @implementation Book
  2.  
  3. - (void)getBookCount{
  4. NSLog(@"Book中getBookCount的实现");
  5. }
  6.  
  7. @end
  8.  
  9. @implementation Customer
  10.  
  11. - (void)getBookCount{
  12. NSLog(@"Customer中getBookCount的实现");
  13. }
  14.  
  15. @end

简单的调用:

  1. Book *book=[[Book alloc]init];
  2. Customer *customer=[[Customer alloc]init];
  3. [customer getBookCount];
  4. [book getBookCount];

  上面几行的代码的结果,不用说大家也能看的懂,接下来看接下来的代码,这个时候大家发现用到了开始顶一个的didBookDelegate:

  1. customer.didBookDelegate=book;
  2. [customer.didBookDelegate getBookCount];

 上面就是将Book的实例,Book实现了BookDelegate,这个时候可将Book的实例赋值给customer中的变量,将自己的实例化对象委托给了didBookDelegate。

以上是委托使用基本的场景,作为实例化对象book可以自己执行其方法,也可以通过委托将执行过程转移。

页面传值

简单的就是A页面数据可以传值给B页面,B页面可以传值给A页面,简单的两个页面传值,页面参考如下:

都是文本框和按钮,跳转方式选取的时Modal:

第一个页面ViewController的定义:

  1. #import <UIKit/UIKit.h>
  2. #import "SecondViewController.h"
  3.  
  4.  
  5. @interface ViewController : UIViewController<StudySubjectDelegate>
  6.  
  7. @property (strong, nonatomic) IBOutlet NSString *firstData;
  8.  
  9.  
  10. @property (weak, nonatomic) IBOutlet UITextField *subjectName;
  11.  
  12. @end

 第二个页面SecondViewController头文件的定义,并且声明了一个委托:

  1. //
  2. // SecondViewController.h
  3. // Sample
  4. //
  5. // Created by keso on 15/2/3.
  6. // Copyright (c) 2015年 keso. All rights reserved.
  7. //
  8.  
  9. #import <UIKit/UIKit.h>
  10.  
  11. @class SecondViewController;
  12. @protocol StudySubjectDelegate <NSObject>
  13.  
  14. - (void)shouldChangeValue:(SecondViewController*)controller;
  15.  
  16. @end
  17.  
  18. @interface SecondViewController : UIViewController
  19.  
  20. @property (assign,nonatomic) id<StudySubjectDelegate> firstViewDelegate;
  21.  
  22.  
  23. @property (weak, nonatomic) IBOutlet NSString *showData;
  24.  
  25. @property (weak, nonatomic) IBOutlet UITextField *studySubject;
  26.  
  27. @end

 ViewController.m中的点击事件:

  1. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
  2. if ([segue.identifier isEqualToString:@"firstEdit"]) {
  3. SecondViewController *controller=segue.destinationViewController;
  4. NSLog(@"%@",self.subjectName.text);
  5. //将自己本身的实例传递给第二个视图
  6. controller.firstViewDelegate=self;
  7. controller.showData=self.subjectName.text;
  8. }
  9. }

 赋值的方式还可以是这样的,其实中的key就是第二个视图定义的属性:

  1. if ([controller respondsToSelector:@selector(setShowData:)]) {
  2. [controller setValue:self.subjectName.text forKey:@"showData"];
  3. }

第二个页面的点击事件就比较简单了,代码如下:

  1. [self.firstViewDelegate shouldChangeValue:self];

上面中其实可以简单的看到oc中的委托就是将自己的实例交给其他对象的成员变量,然后由其成员变量执行实例的工作,的今天不知道为什么有点头疼,说个事情就是最后的第二个页面跳转到一个页面可以接收到值,无法给UITextField赋值,暂时没有搞明白如何才能赋值上去,每次进入就变成了null,有知道可以指点一下,多谢~