一、协议代理(正反向传值)
<1>基本概念
1.协议
- 能力(方法)
- 约定(谁让谁去做)
- 角色(代理和委托)
2.代理
- 代理是一种设计模式,而协议是一种实现代理模式的方法
- 被代理方:知道什么时候做什么事情但不会做的对象
- 代理:有能力做某事,但不知道怎么做的对象
<2>实现步骤
1.声明协议
//协议名称
@protocol FirstDelegate <NSObject>
//方法
//不带参
- (void)firstToSecond;
//带参
- (void)firstToSecondText1:(NSString *)text1 andText2:(NSString *)text2;
@end
2.被代理方需要拥有遵循协议的delegate
@interface ViewController : UIViewController
//<2>声明协议属性
@property (nonatomic, assign) id<FirstDelegate> delegate;
@end
3.设置代理
SecondViewController *second = [[SecondViewController alloc] init];
self.delegate = second;
4.遵循协议
@interface SecondViewController : UIViewController<FirstDelegate>
@end
5.实现方法
- (void)firstToSecond{
self.view.backgroundColor = [UIColor magentaColor];
}
6.调用代理方法
if ([self.delegate respondsToSelector:@selector(firstToSecond)]) {
[self.delegate firstToSecond];
}
二、单例(正反向传值)
<1>系统单例
1.获取应用程序唯一的代理对象
AppDelegate *app = [[UIApplication sharedApplication] delegate];
2.赋值
appDelegate.text1 = textField1.text;
appDelegate.text2 = textField2.text;
3.获取应用程序唯一的代理对象
AppDelegate *app = [[UIApplication sharedApplication] delegate];
4.取值
NSString *str1 = app.text1;
NSString *str2 = app.text2;
<2>自定义的单例
1.创建单例
#import <Foundation/Foundation.h>
@interface SingleTon : NSObject
@property (nonatomic, strong) NSString *text1;
@property (nonatomic, strong) NSString *text2;
//类方法
+ (SingleTon *)sharedSingleTon;
@end
#import "SingleTon.h"
//static静态变量的对象
static SingleTon *singleTon = nil;
@implementation SingleTon
//方法的实现
+ (SingleTon *)sharedSingleTon{
//dispatch_once 线程管理 唯一线程 GCD 执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (singleTon == nil) {
singleTon = [[SingleTon alloc] init];
}
});
return singleTon;
}
@end
2.其他步骤与使用系统单例一致
三、属性(正向传值)
1.设置属性
@interface SecondViewController : UIViewController
//<1>属性正向传值:声明相应属性用于接收数值
@property (nonatomic, strong) NSString *text1;
@end
2.赋值
second.text1 = text1.text;
3.取值
label1.text = self.text1;
四、通知(反向传值)
<1>注意:
- 只有当当前界面已经存在即添加到父视图后,后期发送的通知才能执行
- 通知需要先接受后发送才能有效
- 通知中心:整个工程有且只有一个 单例
<2>使用步骤
1.发送通知:postNotificationName:object:
- 不携带参数
/*
第一个参数:通知名称
第二个参数:通知携带的参数
*/
[[NSNotificationCenter defaultCenter] postNotificationName:@"123" object:nil];
- 携带参数
/*
第一个参数:通知名称
第二个参数:通知携带的参数
*/
[[NSNotificationCenter defaultCenter] postNotificationName:@"456" object:_textField.text];
- 携带大参数
/*
第一个参数:通知名称
第二个参数:通知携带的参数
第三个参数:通知携带的较大的参数 字典类型
*/
[[NSNotificationCenter defaultCenter] postNotificationName:@"789" object:@"qwe" userInfo:@{@"qq":@"weixin"}];
2.接收通知:addObserver:selector:name:object:
/*
第一个参数:谁接受通知,接收完通知之后谁做相应操作 self
第二个参数:接收完通知之后所做的操作 方法不带参数
第三个参数:通知名称
第四个参数:nil
*/
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notification) name:@"123" object:nil];
/*
第一个参数:谁接受通知,接收完通知之后谁做相应操作 self
第二个参数:接收完通知之后所做的操作 方法带参数
第三个参数:通知名称
第四个参数:nil
*/
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationCenter:) name:@"456" object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(notificationUserinfo:) name:@"789" object:nil];
3.接收通知后响应操作
- (void)notification{
self.view.backgroundColor = [UIColor purpleColor];
}
- (void)notificationCenter:(NSNotification *)notif{
//获取通知所带的参数
NSString *str = (NSString *)[notif object];
_label.text =str;
}
- (void)notificationUserinfo:(NSNotification *)notif{
//获取携带的参数
NSString *str = (NSString *)[notif object];
//获取大参数
NSDictionary *dic = [notif userInfo];
NSLog(@"%@, %@",str, dic);
}
五、block(反向传值)
<1>基本认识
1.在类中,定义一个Block变量,就像定义一个函数;
2.Block可以定义在方法内部,也可以定义在方法外部(文件级全局变量);
3.只有调用Block时候,才会执行其{}体内的代码;
<2>基本使用
- 作为一个本地变量
returnType (^blockName)(parameterTypes) = ^returnType(parameters) {
//blablabla
};
//^表示block,()参数列表,{}执行代码
int (^add)(int, int) = ^int(int a, int b) {
//执行的代码
return a + b
}
- 作为@property
@property (nonatomic, copy) returnType (^blockName)(parameterTypes);
- 作为方法的形参
- (void)someMethodThatTakesABlock:(returnType (^)(parameterTypes))blockName;
- 作为方法实参的时候被调用
[someObject someMethodThatTakesABlock: ^returnType (parameters) {...}];
- 使用typedef来定义block,可以事半功倍
typedef returnType (^TypeName)(parameterTypes);
TypeName blockName = ^returnType(parameters) {...};
typedef double(^BlockType)(double a, double b)
BlockType addBlock = ^double(double a, double b) {
return a + b
}
<3>反向传值
1.block声明
- 第一个参数:返回值类型
- 第二个参数:block的名称
- 第三个参数:block所携带的参数 不携带参数,小括号里为空,若携带参数,将类型及名称写入,若携带多个参数,用,分开
typedef void(^MyBlock)(NSString *text1, NSString *text2);
2.设置block属性
@interface SecondViewController : UIViewController<UITextFieldDelegate>
@property (nonatomic, strong) MyBlock block;
@end
3.实现block
second.block = ^(NSString *text1, NSString *text2){
UILabel *label1 = (UILabel *)[self.view viewWithTag:1001];
UILabel *label2 = (UILabel *)[self.view viewWithTag:1002];
label1.text = text1;
label2.text = text2;
};
4.调用block传值
self.block(textField1.text, textField2.text);
5.注意:block在实现是不会执行{}中的代码,只有在被调用用时(回调)才会执行{}中的代码。