六大传值--(属性/代理/通知/KVO/KVC/Tag/单例/Block/全局)
先创建两个ViewController:
1,先在Appdelegate.m里设置一个AViewController.m 为rootViewController,并创建一个BViewController
在AViewController.m中导入BViewController.h,,,创建一个SingleOne继承于NSObject作为单例类
import "AViewController.h"
import "BViewController.h"
//单例
import "SingleOne.h"
//代理传值,遵循协议Nextprotocol
@interface AViewController ()
{
BViewController *bView;
}
@end
@implementation AViewController
-
(void)viewDidLoad {
[superviewDidLoad];self.title =@"AViewController";
self.view.backgroundColor = [UIColorwhiteColor];//作一个跳转button
UIBarButtonItem *item = [[UIBarButtonItemalloc]initWithTitle:@"跳转"style:UIBarButtonItemStylePlaintarget:selfaction:@selector(touchAction:)];
self.navigationItem.rightBarButtonItem = item;
//声明一个aTextFiled
UITextField *aTextField = [[UITextFieldalloc]initWithFrame:CGRectMake([UIScreenmainScreen].bounds.size.width/2-150, [UIScreenmainScreen].bounds.size.height/2-25,300, 30)];
aTextField.layer.borderWidth =2;
aTextField.layer.borderColor = [UIColorgrayColor].CGColor;
aTextField.layer.masksToBounds =YES;
aTextField.tag = 1000;
aTextField.delegate = self;
[self.viewaddSubview:aTextField];
// aTextField.text = @"李涛你个混蛋";
//反正是KVO时就一定要放在viewdidLoad这里,不会跳两第二次时会报错,说这个bView已经消亡了但还有人在监听它
bView = [[BViewController alloc]init];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
-(void)touchAction:(UIButton *)sender
{
//用tag传值
UITextField *aTextFiled = (UITextField *)[self.viewviewWithTag:1000];
// NSLog(@"aTextFiled.text = %@",aTextFiled.text);
// BViewController *bView = [[BViewControlleralloc]init];
/*-------------------单例传值:从A---->>B ----------------------*/
SingleOne *onlyOne = [SingleOneshareData];
//让单例作为中介去接收A页面要传的值,
onlyOne.value = aTextFiled.text;
/*-------------------block传值:从B---->>A -------------------*/
[bView setMblock:^(NSString *string){ //注意类型,也可以用id
aTextFiled.text = string;
}];
bView.mblock = ^(id string){
aTextFiled.text = string;
};
/*---------------------属性传值:从A--->>B --------------------*/
bView.text1 = aTextFiled.text;
/*---------------------KVC传值-------------------------*/
[bView setValue:aTextFiled.textforKey:@"_name"];
[bView setValue:aTextFiled.textforKey:bView.text1]; //或者
/*---------------------通知传值 B--->>A ------------------------*/
//
如果是从A传到B的话,这里写发通知,B.m里要创建一个init方法,在里面写监听并在里面创建接收容器才能成功(因为程序先执行init方法再到viewDidLoad方法,当传值过去时在init就开始监听,如果这里没有创建textField接收,那就传不过去了,所以要在init里同时创建接收器(生命周期的问题));
//这里是从B到A:注册监听:从B传到A话因为从A跳转到B时已经创建好A了,所以
[[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(aAction:)name:@"amessage"object:nil];
/*---------------------代理传值 B--->>A -------------------*/
bView.delegate = self; //设置代理
/---------------------KVO回传值 B--->>A-------------------/
//注册观察者:如果用了KVO一定要把bView的初始化放在上面的viewDidLoad里
[bView addObserver:self forKeyPath:@"test1" options:NSKeyValueObservingOptionNew context:nil];
//把更改之后的值提供给观察者的回调方法
[self.navigationControllerpushViewController:bView animated:YES];
}
pragma mark============代理传值:实现协议方法==============
-(void)transferString:(NSString *)string
{
UITextField *aTextField = (UITextField *)[self.viewviewWithTag:1000];
aTextField.text = string;
}
pragma mark -----------通知回调方法实现--------------
-(void)aAction:(NSNotification *)sender
{
UITextField *aField = (UITextField *)[self.viewviewWithTag:1000];
aField.text = sender.userInfo[@"akey"];
}
pragma mark ------------- KVO回调 ------------------
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary
{
UITextField *aTextField = (UITextField *)[self.view viewWithTag:1000];
//此处监听键路径key的值有没有发生变化
if ([keyPath isEqualToString:@"text1"]) { //如果观察的对象是text1
aTextField.text = bView.text1;
}
}
//移除通知的监听者 和 KVO的观察者(如果不移除,会变成野指针)
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"amessage" object:nil]; //移除通知监听者
[bView removeObserver:self forKeyPath:@"text1"]; //移除KVO观察者
}
- (void)didReceiveMemoryWarning {
[superdidReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
BVIewController.h里
//
// BViewController.h
// test传值
//
// Created by ibokan on 16/3/16.
// Copyright © 2016年谭其伟. All rights reserved.
//
import
pragma mark ======Block传值=========
typedef void(^TransferValue) (NSString *string);
pragma mark---------代理传值-------------
//声明一个协议
@protocol Nextprotocol
//协议里的方法(让遵循该协议的类实现,自己不实现)
-(void)transferString:(NSString *)string;
@end
@interface BViewController : UIViewController
{
//KVC传值需要有一个实例变量作为key
NSString *_name;
}
//把block作为属性
@property(nonatomic,copy)TransferValue mblock;
//属性传值
@property(nonatomic,readwrite,strong)NSString *text1;
pragma mark---------代理传值-------------
//有一个遵循协议的代理属性
@property(nonatomic,readwrite,strong)id
@end
BViewController.m里
//
// BViewController.m
// test传值
//
// Created by ibokan on 16/3/16.
// Copyright © 2016年谭其伟. All rights reserved.
//
import "BViewController.h"
//单例
import "SingleOne.h"
@interface BViewController ()
{
UITextField *bTextFiled;
}
@end
@implementation BViewController
-
(void)viewDidLoad {
[superviewDidLoad];self.title =@"BViewController";
self.view.backgroundColor = [UIColorredColor];
//声明一个返回button
UIButton *aButton = [UIButtonbuttonWithType:UIButtonTypeCustom];
aButton.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-50,150, 100, 30);
[aButton setTitleColor:[UIColorblackColor] forState:UIControlStateNormal];
[aButton addTarget:selfaction:@selector(backAction:)forControlEvents:UIControlEventTouchUpInside];
[aButton setTitle:@"返回"forState:UIControlStateNormal];
[self.viewaddSubview:aButton];
//使用全局传值:声明一个bTextFiled
bTextFiled = [[UITextFieldalloc]initWithFrame:CGRectMake([UIScreenmainScreen].bounds.size.width/2-150, [UIScreen mainScreen].bounds.size.height/2-100,300, 30)];
bTextFiled.layer.borderColor = [UIColorblackColor].CGColor;
bTextFiled.layer.borderWidth =2;
//_btextFiled.delegate = self;
bTextFiled.text = [NSStringstring]; //相当于nil
bTextFiled.layer.masksToBounds =YES;
[self.viewaddSubview:bTextFiled];
pragma mark ------单例传值接收:再间接传给B页面-----------------
bTextFiled.text = [SingleOneshareData].value;
pragma mark ++++++++++++属性传值++++++++++++++++
bTextFiled.text =self.text1;
//KVC传值
self.text1 =_name;
bTextFiled.text =self.text1;
pragma mark ==============通知传值:回传=====================
//发送通知
[[NSNotificationCenterdefaultCenter] postNotificationName:@"amessage"object:selfuserInfo:@{@"akey":bTextFiled.text}];
}
-(void)backAction:(UIButton *)sender
{
/*-------------block传值要写在方法里----------------*/
_mblock(bTextFiled.text);
self.mblock(bTextFiled.text);
/*---------------代理传值-------------------------*/
if (self.delegate && [self.delegateconformsToProtocol:@protocol(Nextprotocol)]) {
[self.delegatetransferString:bTextFiled.text];
}
[self.navigationControllerpopViewControllerAnimated:YES];
}
- (void)didReceiveMemoryWarning {
[superdidReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
单例类:
SingleOne.h
// SingleOne.h
// test传值
//
// Created by ibokan on 16/3/16.
// Copyright © 2016年谭其伟. All rights reserved.
//
import
@interface SingleOne : NSObject
//创建一个单例//如果在单线程里可以用nonatomic,如果在多线程里一定要用atomic,保证是只有一个在调用,不然在多线程里面如果多个方法调用修改单例类里的属性时会冲突
@property(atomic,readwrite,strong)NSString *value;
//声明一个类方法
+(SingleOne *)shareData;
@end
SingleOne.m里
//
// SingleOne.m
// test传值
//
// Created by ibokan on 16/3/16.
// Copyright © 2016年谭其伟. All rights reserved.
//
import "SingleOne.h"
//声明一个表态实例对象,让其为空
static SingleOne *onlyOne =nil;
@implementation SingleOne
//实现方法,判断是否为空,是就创建一个全局实例给它
+(SingleOne *)shareData
{
if (onlyOne ==nil) {
onlyOne = [[SingleOnealloc]init];
}
returnonlyOne;
}
//避免alloc/new创建新的实例变量--->增加一个互斥锁
+(id)allocWithZone:(struct_NSZone *)zone
{
@synchronized(self) {
if (onlyOne ==nil) {
onlyOne = [superallocWithZone:zone];
}
}
returnonlyOne;
}
//避免copy,需要实现NSCopying协议
-(id)copyWithZone:(NSZone *)zone
{
return self;
}
@end