思考:在一个类中,能否让一个类必须实现某种方法?
一、 非正式协议
非正式协议就是类别,即凡是NSObject或其子类的类别,都是非正式协议。
二、协议(protocol)
2.1、 what
一些方法的声明,写到.h文件中。
方法有2种,一是必须实现,二是选择实现。
2.2 、协议的作用
供其他的类去遵守,如果一个类遵守了一个协议,就应该实现这个协议中定义的必须要实现的方法。
2.3、如何定义一个协议
@protocol XXX <NSObject>
@end
2.4 如何遵守协议
@interface 类名:NSobject<XXX1>
@end
2.4、使用注意
- 就一个用途,用来声明一大堆的方法(不能声明成员变量),不能写实现
- 只要某个类遵守了这个协议,就永拥有了这个协议中的所有方法声明
- 只要父类遵守了某个协议,那么子类也遵守
- Protocol声明的方法可以让任何类去实现
- OC不能继承多个类,但是能遵守多个协议
- 基协议:<NSObject>是基协议,是最根本最根本的协议,其中声明了很多最基本的方法,比如description,retain,release
- 协议可以遵守协议,一个协议遵守了另一个协议,就可以拥有另一份协议中的方法声明
三、代理模式
3.1 what
传入的对象,代替当前类完成了某个功能,成为代理模式
3.2 思路
- 定义一个协议,里面声明代理类需要实现的方法列表,比如这里一个代理类需要实现feedbaby与babysleep方法。
- 创建一个代理类(保姆),遵守上面的代理协议
- 在需要代理的类中,定义一个对象类型为id且遵守代理协议的成员变量
- 在baby类中调用成员变量_delegate(代理)的方法,调用代理的方法
3.3 代理的使用场合 - 监听器
- 通知的场合
- 有些事情,不想自己处理,想要交给别人处理
代码实例,逆向传值
XieYiOneViewController
#import <UIKit/UIKit.h>
@interface XieYiOneViewController : UIViewController
@end
#import "XieYiOneViewController.h"
#import "XieYiTwoViewController.h"
@interface XieYiOneViewController ()<XieYiTwoDelegate>
@property (weak, nonatomic) IBOutlet UITextField *telePhoneField;
- (IBAction)btnClick:(id)sender;
@end
@implementation XieYiOneViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)btnClick:(id)sender {
XieYiTwoViewController *nextVC = [[XieYiTwoViewController alloc] init];
nextVC.delegate = self;
[self.navigationController pushViewController:nextVC animated:YES];
}
//协议传值(逆传)
#pragma mark -XieYiTwoDelegate
-(void)ChangeViewController:(XieYiTwoViewController *)viewController changeText:(NSString *)text
{
self.telePhoneField.text = text;
}
@end
XieYiTwoViewController
#import <UIKit/UIKit.h>
@class XieYiTwoViewController;
@protocol XieYiTwoDelegate <NSObject>
- (void)ChangeViewController:(XieYiTwoViewController *)viewController changeText:(NSString *)text;
@end
@interface XieYiTwoViewController : UIViewController
@property (nonatomic,assign) id <XieYiTwoDelegate> delegate;
@end
#import "XieYiTwoViewController.h"
@interface XieYiTwoViewController ()
@property (weak, nonatomic) IBOutlet UITextField *telePhonefield;
- (IBAction)btnClick:(id)sender;
@end
@implementation XieYiTwoViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
//协议传值
- (IBAction)btnClick:(id)sender {
if ([self.delegate respondsToSelector:@selector(ChangeViewController:changeText:)]) {
[self.delegate ChangeViewController:self changeText:self.telePhonefield.text];
}
[self.navigationController popViewControllerAnimated:YES];
}
@end
疑问:
-
@property (nonatomic,assign) id <XieYiTwoDelegate> delegate
delegate为什么用weak或assign修饰,而不用strong修饰?
在ARC中,只要对象没有强指针就会自动释放。
一句话:防止循环引用
详细解释 -
@property (weak, nonatomic) IBOutlet UITextField *telePhonefield;
控件为什么用weak修饰?
代码如下
由图可知,UISwitch用strong和weak修饰都没有影响,但是官方建议用weak。
- 代理为什么用weak
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UIScrollView *sl = [[UIScrollView alloc] init];
sl.delegate = self;
[self.view addSubview:sl];
}
关系图.png
网友评论