iOS--开发中的六大传值(OC中的常用传值)

六大传值--(属性/代理/通知/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 *)change context:(void *)context
{
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)iddelegate;

@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

你可能感兴趣的:(iOS--开发中的六大传值(OC中的常用传值))