ios页面传值:正向、反向

iOS开发中,页面传值是很常见的,但是页面传值你究竟知道多少呢?笔者这篇文章就是给大家介绍一下页面传值的具体方式,有不足之处,欢迎大家指正,希望能和大家共同进步。说明一下:这里所说的正向、反向传值是指相关联的两个页面间的传值。

目前我所了解和掌握的传值方式有:属性传值、代理传值、Block传值、KVO传值、通知传值、单例传值、KVC传值。

下面我们来一一看下它们究竟是怎样进行操作和传值的呢?

假设我们现在有控制器(页面)A和控制器(页面)B,A->push->B,即A是B的上一个页面(控制器)。

  1. 属性传值
    用法:正向传值
    需求:当A-push到B时,B中有一个Label需要显示从A中的一个TextField输入的内容,这时我们需要用到正向传值。

    A控制器.m文件:

    #import "A_ViewController.h"
    #import "B_ViewController.h"
    
    @interface A_ViewController ()
    
    @property (nonatomic, strong) UITextField *aTextField;
    
    @end
    
    @implementation A_ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.title = @"A";
        self.view.backgroundColor = [UIColor whiteColor];
        self.aTextField = [[UITextField alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 200, 100, 30)];
    
        self.aTextField.layer.borderColor = [UIColor grayColor].CGColor;
        self.aTextField.layer.borderWidth = 1;
        [self.view addSubview:self.aTextField];
    
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 280, 100, 30);
        [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [button setTitle:@"传到B" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
    
    }
    
    - (void)buttonAction:(UIButton *)sender {
    
        /**
         什么时候可以用 属性 传值
    
         A 传到 B,正向传值
    
         B 在 A页面 提前初始化
    
         **/
    
        B_ViewController *bViewController = [[B_ViewController alloc] init];
        bViewController.string = self.aTextField.text;
        [self.navigationController pushViewController:bViewController animated:YES];
    
    }
    
    @end
    

    B控制器.h文件:

    #import <UIKit/UIKit.h>
    
    @interface B_ViewController : UIViewController
    
    @property (nonatomic, copy) NSString *string;
    
    @end
    

    B控制器.m文件:

    #import "B_ViewController.h"
    
    @interface B_ViewController ()
    
    @end
    
    @implementation B_ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.title = @"B";
        self.view.backgroundColor = [UIColor whiteColor];
    
        self.view.backgroundColor = [UIColor whiteColor];
        UILabel *bLabel = [[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 200, 100, 30)];
    
        bLabel.layer.borderColor = [UIColor grayColor].CGColor;
        bLabel.layer.borderWidth = 1;
        [self.view addSubview:bLabel];
    
        bLabel.text = self.string;
    }
    
    @end
    
  2. 代理传值
    用法:反向传值:
    需求:A-push到B,当B消失的时候,A中有一个Label需要显示从B中的一个TextField输入的内容,这时我们需要用到反向传值。

    A控制器.m文件:

    #import "A_ViewController.h"
    #import "B_ViewController.h"
    
    @interface A_ViewController () <BToADelegate>
    
    @property (nonatomic, strong) UILabel *aLabel;
    
    @end
    
    @implementation A_ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.title = @"A";
        self.view.backgroundColor = [UIColor whiteColor];
        self.aLabel = [[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 200, 100, 30)];
    
        self.aLabel.layer.borderColor = [UIColor grayColor].CGColor;
        self.aLabel.layer.borderWidth = 1;
        [self.view addSubview:self.aLabel];
    
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 280, 100, 30);
        [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [button setTitle:@"push到B" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
    
    }
    
    -(void)buttonAction:(UIButton *)sender {
    
        B_ViewController *bViewController = [[B_ViewController alloc] init];
        //设置代理
        bViewController.delegate = self;
        [self.navigationController pushViewController:bViewController animated:YES];
    }
    
    /**
     什么时候可以用 代理 传值
    
     B 传到 A,反向传值
    
     B 在 A页面 初始化
    
     设置A为B的代理
    
     执行代理方法
    
     **/
    - (void)transferString:(NSString *)string {
    
        self.aLabel.text = string;
    }
    
    @end
    

    B控制器.h文件:

    #import <UIKit/UIKit.h>
    
    // 声明代理
    @protocol BToADelegate <NSObject>
    
    // 代理方法
    - (void)transferString:(NSString *)string;
    
    @end
    
    @interface B_ViewController : UIViewController
    
    // 代理属性
    @property (nonatomic, weak) id<BToADelegate> delegate;
    
    @end
    

    B控制器.m文件:

    #import "B_ViewController.h"
    
    @interface B_ViewController ()
    
    @property (nonatomic, strong) UITextField *bTextField;;
    
    @end
    
    @implementation B_ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.title = @"B";
        self.view.backgroundColor = [UIColor whiteColor];
    
        self.view.backgroundColor = [UIColor whiteColor];
        self.bTextField = [[UITextField alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 200, 100, 30)];
    
        self.bTextField.layer.borderColor = [UIColor grayColor].CGColor;
        self.bTextField.layer.borderWidth = 1;
        [self.view addSubview:self.bTextField];
    
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 280, 100, 30);
        [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [button setTitle:@"传值A" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
    
    }
    
    - (void)buttonAction:(UIButton *)sender {
    
        // 判断有没有代理以及代理是否响应代理方法
        if (self.delegate && [self.delegate respondsToSelector:@selector(transferString:)]) {
            [self.delegate transferString:self.bTextField.text];
        }
    
        [self.navigationController popToRootViewControllerAnimated:YES];
    }
    
    @end
    
  3. Block传值
    用法:反向传值:
    需求:A-push到B,当B消失的时候,A中有一个Label需要显示从B中的一个TextField输入的内容,这时我们需要用到反向传值。

    A控制器.m文件:

    #import "A_ViewController.h"
    #import "B_ViewController.h"
    
    @interface A_ViewController ()
    
    @property (nonatomic ,strong) UILabel *aLabel;
    
    @end
    
    @implementation A_ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.title = @"A";
        self.view.backgroundColor = [UIColor whiteColor];
        self.aLabel = [[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 200, 100, 30)];
    
        self.aLabel.layer.borderColor = [UIColor grayColor].CGColor;
        self.aLabel.layer.borderWidth = 1;
        [self.view addSubview:self.aLabel];
    
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 280, 100, 30);
        [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [button setTitle:@"push到B" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
    
    }
    
    - (void)buttonAction:(UIButton *)sender {
    
        B_ViewController *bViewController = [[B_ViewController alloc] init];
    
        __weak __typeof(self) weakSelf = self;
        // block 回调接收
        [bViewController setBlock:^(NSString *string){
            weakSelf.aLabel.text = string;
        }];
    
        [self.navigationController pushViewController:bViewController animated:YES];
    }
    

    B控制器.h文件:

    #import <UIKit/UIKit.h>
    
    // 定义一个block
    typedef void(^BToAblock)(NSString *string);
    
    @interface B_ViewController : UIViewController
    
    // block 属性
    @property (nonatomic, copy)BToAblock block;
    
    @end
    

    B控制器.m文件:

    #import "B_ViewController.h"
    
    @interface B_ViewController ()
    
    @property (nonatomic, strong) UITextField *bTextField;
    
    @end
    
    @implementation B_ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.title = @"B";
        self.view.backgroundColor = [UIColor whiteColor];
    
        self.view.backgroundColor = [UIColor whiteColor];
        self.bTextField = [[UITextField alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 200, 100, 30)];
    
        self.bTextField.layer.borderColor = [UIColor grayColor].CGColor;
        self.bTextField.layer.borderWidth = 1;
        [self.view addSubview:self.bTextField];
    
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 280, 100, 30);
        [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [button setTitle:@"传值A" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
    
    }
    
    - (void)buttonAction:(UIButton *)sender {
        /**
         Blcok 传值
    
         反向传值
    
         B 传到 A
         */
        _block(self.bTextField.text);
        [self.navigationController popToRootViewControllerAnimated:YES];
    }
    
    @end
    
  4. KVO传值
    用法:反向传值:
    需求:A-push到B,当B消失的时候,A中有一个Label需要显示从B中的一个TextField输入的内容,这时我们需要用到反向传值。

    A控制器.m文件:

    #import "A_ViewController.h"
    #import "B_ViewController.h"
    
    @interface A_ViewController ()
    
    @property (nonatomic, strong) UILabel *aLabel;
    @property (nonatomic, strong) B_ViewController *bViewController;
    
    @end
    
    @implementation A_ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.title = @"A";
        self.view.backgroundColor = [UIColor whiteColor];
        self.aLabel = [[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 200, 100, 30)];
    
        self.aLabel.layer.borderColor = [UIColor grayColor].CGColor;
        self.aLabel.layer.borderWidth = 1;
        [self.view addSubview:self.aLabel];
    
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 280, 100, 30);
        [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [button setTitle:@"push到B" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
    
        /**
         KVO 创建 三步一定要写
            1. 注册观察者
            2. KVO的回调
            3. 移除观察者
    
         */
    
        // B 传到 A ,反向传值
        //注册观察者,注意:观察者的注册和移除要对应,如果移除时发现没有注册观察者,程序会crash
         self.bViewController = [[B_ViewController alloc] init];
        [self.bViewController addObserver:self forKeyPath:@"string" options:NSKeyValueObservingOptionNew context:nil];
    }
    
    - (void)buttonAction:(UIButton *)sender {
    
        [self.navigationController pushViewController:self.bViewController animated:YES];
    
    }
    
    // KVO的回调
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    
        if ([keyPath isEqualToString:@"string"]) {
            self.aLabel.text = self.bViewController.string;
        }
    
    }
    // KVO 的移除方式  (和通知一样要移除)
    - (void)dealloc {
    
        [self.bViewController removeObserver:self forKeyPath:@"string"];
    }
    
    @end
    

    B控制器.h文件:

    #import <UIKit/UIKit.h>
    
    @interface B_ViewController : UIViewController
    
    @property (nonatomic, copy) NSString *string;
    
    @end
    

    B控制器.m文件:

    #import "B_ViewController.h"
    
    @interface B_ViewController ()
    
    @property (nonatomic, strong) UITextField *bTextField;
    
    @end
    
    @implementation B_ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.title = @"B";
        self.view.backgroundColor = [UIColor whiteColor];
    
        self.view.backgroundColor = [UIColor whiteColor];
        self.bTextField = [[UITextField alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 200, 100, 30)];
    
        self.bTextField.layer.borderColor = [UIColor grayColor].CGColor;
        self.bTextField.layer.borderWidth = 1;
        [self.view addSubview:self.bTextField];
    
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 280, 100, 30);
        [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [button setTitle:@"传值A" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
    
    }
    
    - (void)buttonAction:(UIButton *)sender {
        // KVO
        // 把self.bTextfield.text 赋值给当前属性
        // 在A中 监听 当前属性
        self.string = self.bTextField.text;
    
        [self.navigationController popToRootViewControllerAnimated:YES];
    }
    
    @end
    
  5. 通知传值
    用法:正向传值
    需求:当A-push到B时,B中有一个Label需要显示从A中的一个TextField输入的内容,这时我们需要用到正向传值。

    用法:反向传值:
    需求:A-push到B,当B消失的时候,A中有一个Label需要显示从B中的一个TextField输入的内容,这时我们需要用到反向传值。

    我们在此将两种传值情况写到一个Demo中,所以将上述Label换为Textfield即可,如下:

    A控制器.m文件:

    #import "A_ViewController.h"
    #import "B_ViewController.h"
    
    @interface A_ViewController ()
    
    @property (nonatomic, strong) UITextField *aTextField;
    
    @end
    
    @implementation A_ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.title = @"A";
        self.view.backgroundColor = [UIColor whiteColor];
        self.aTextField = [[UITextField alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 200, 100, 30)];
    
        self.aTextField.layer.borderColor = [UIColor grayColor].CGColor;
        self.aTextField.layer.borderWidth = 1;
        [self.view addSubview:self.aTextField];
    
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 280, 100, 30);
        [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [button setTitle:@"传到B" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
    
        // 接收通知
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tzAction:) name:@"B2A" object:nil];
    }
    
    - (void)buttonAction:(UIButton *)sender {
    
        // 通知传值 一般是用于回传
    
        // 现在是 A传到B,正向传值
    
        // 发送通知的方法 要写在执行方法里面
    
        B_ViewController *bViewController = [[B_ViewController alloc] init];
    
        [[NSNotificationCenter defaultCenter] postNotificationName:@"A2B" object:nil userInfo:@{@"key":self.aTextField.text}];
    
        [self.navigationController pushViewController:bViewController animated:YES];
    
    }
    
    // 回调通知
    - (void)tzAction:(NSNotification *)sender {
    
        self.aTextField.text = sender.userInfo[@"key"];
    }
    
    // 移除通知
    - (void)dealloc {
    
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    @end
    

    B控制器.m文件:

    #import "B_ViewController.h"
    
    @interface B_ViewController ()
    
    @property (nonatomic, strong) UITextField *bTextField;
    
    @end
    
    @implementation B_ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.title = @"B";
        self.view.backgroundColor = [UIColor whiteColor];
    
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 280, 100, 30);
        [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [button setTitle:@"传值A" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
    }
    
    //如果是从A传到B的话,B.m里要创建一个init方法,在里面写监听并在里面创建接收容器才能成功(因为程序先执行init方法再到viewDidLoad方法,当传值过去时在init就开始监听,如果这里没有创建textField接收,那就传不过去了,所以要在init里同时创建接收器(生命周期的问题));
    -(instancetype)init
    {
        if (self = [super init]) {
    
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tzAction:) name:@"A2B" object:nil];
    
            self.bTextField = [[UITextField alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 200, 100, 30)];
    
            self.bTextField.layer.borderColor = [UIColor grayColor].CGColor;
            self.bTextField.layer.borderWidth = 1;
            [self.view addSubview:self.bTextField];
    
        }
    
        return self;
    }
    
    //接收通知
    - (void)tzAction:(NSNotification *)sender {
    
        self.bTextField.text = sender.userInfo[@"key"];
    
    }
    
    // 移除通知
    - (void)dealloc  {
    
        // 移除所有
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    
        // 移除某个
        // [[NSNotificationCenter defaultCenter] removeObserver:self name:@"tz" object:nil];
    }
    
    //发送通知
    - (void)buttonAction:(UIButton *)sender {
        // B传到A,反向传值
        [[NSNotificationCenter defaultCenter] postNotificationName:@"B2A" object:nil userInfo:@{@"key":self.bTextField.text}];
    
        [self.navigationController popToRootViewControllerAnimated:YES];
    
    }
    
    @end
    
  6. 单例传值
    用法:正向传值
    需求:当A-push到B时,B中有一个Label需要显示从A中的一个TextField输入的内容,这时我们需要用到正向传值。

    用法:反向传值:
    需求:A-push到B,当B消失的时候,A中有一个Label需要显示从B中的一个TextField输入的内容,这时我们需要用到反向传值。

    我们在此将两种传值情况写到一个Demo中,所以将上述Label换为Textfield即可,如下:

    A控制器.m文件:

    #import "A_ViewController.h"
    #import "B_ViewController.h"
    #import "DanLi.h"
    
    @interface A_ViewController ()
    
    @property (nonatomic, strong) UITextField *aTextField;
    
    @end
    
    @implementation A_ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
    
        self.title = @"A";
        self.view.backgroundColor = [UIColor whiteColor];
        self.aTextField = [[UITextField alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 200, 100, 30)];
    
        self.aTextField.layer.borderColor = [UIColor grayColor].CGColor;
        self.aTextField.layer.borderWidth = 1;
        [self.view addSubview:self.aTextField];
    
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 280, 100, 30);
        [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [button setTitle:@"传到B" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
    
    }
    
    - (void)viewWillAppear:(BOOL)animated
    {
        // 单例 传值 B传到A (可以双向传值)
        DanLi *danli = [[DanLi alloc] init];
    
        self.aTextField.text = danli.value;
    }
    
    - (void)buttonAction:(UIButton *)sender {
    
        // 单例 传值 A传到B (可以双向传值)
        DanLi *danli = [DanLi sharedDanLi];
        danli.value = self.aTextField.text;
    
        B_ViewController *bViewController = [[B_ViewController alloc] init];
    
        [self.navigationController pushViewController:bViewController animated:YES];
    
    }
    

    B控制器.m文件:

    #import "B_ViewController.h"
    #import "DanLi.h"
    
    @interface B_ViewController ()
    
    @property (nonatomic, strong) UITextField *bTextField;
    
    @end
    
    @implementation B_ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.title = @"B";
        self.view.backgroundColor = [UIColor whiteColor];
    
        self.view.backgroundColor = [UIColor whiteColor];
        self.bTextField = [[UITextField alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 200, 100, 30)];
    
        self.bTextField.layer.borderColor = [UIColor grayColor].CGColor;
        self.bTextField.layer.borderWidth = 1;
        [self.view addSubview:self.bTextField];
    
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 280, 100, 30);
        [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [button setTitle:@"传值A" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
    
        self.bTextField.text = [DanLi sharedDanLi].value;
    }
    
    - (void)buttonAction:(UIButton *)sender {
        //B传给A
        [DanLi sharedDanLi].value = self.bTextField.text;
        [self.navigationController popToRootViewControllerAnimated:YES];
    }
    
    @end
    

    单例类.h文件:

    #import <Foundation/Foundation.h>
    
    @interface DanLi : NSObject
    
    //创建一个单例//如果在单线程里可以用nonatomic,如果在多线程里一定要用atomic,保证是只有一个在调用,不然在多线程里面如果多个方法调用修改单例类里的属性时会冲突
    @property (atomic, copy) NSString *value;
    
    + (DanLi *)sharedDanLi;
    
    @end
    

    单例类.m文件:

    #import "DanLi.h"
    
    static DanLi *danli = nil;
    
    @implementation DanLi
    
    //实现方法,判断是否为空,是就创建一个全局实例给它
    + (DanLi *)sharedDanLi {
    
        if (danli == nil) {
            danli = [[DanLi alloc] init];
        }
        return danli;
    }
    
    //避免alloc/new创建新的实例变量--->增加一个互斥锁
    + (id)allocWithZone:(struct _NSZone *)zone {
    
        @synchronized(self) {
            if (danli == nil) {
                danli = [super allocWithZone:zone];
            }
        }
        return danli;
    }
    
    //避免copy,需要实现NSCopying协议
    - (id)copyWithZone:(NSZone *)zone {
        return self;
    }
    
    @end
    
  7. KVC传值
    用法:正向传值
    需求:当A-push到B时,B中有一个Label需要显示从A中的一个TextField输入的内容,这时我们需要用到正向传值。

    A控制器.m文件:

    #import "A_ViewController.h"
    #import "B_ViewController.h"
    
    @interface A_ViewController ()
    
    @property (nonatomic, strong) UITextField *aTextField;
    
    @end
    
    @implementation A_ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        self.title = @"A";
        self.view.backgroundColor = [UIColor whiteColor];
        self.aTextField = [[UITextField alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 200, 100, 30)];
    
        self.aTextField.layer.borderColor = [UIColor grayColor].CGColor;
        self.aTextField.layer.borderWidth = 1;
        [self.view addSubview:self.aTextField];
    
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 280, 100, 30);
        [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [button setTitle:@"传到B" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
    }
    
    - (void)buttonAction:(UIButton *)sender {
    
        B_ViewController *bViewController = [[B_ViewController alloc] init];
    
        /**
            KVC 传值:这里只能传A传到B (因为 B在A页面提前初始化)
            B 有个属性 string
            用B对象 给B属性赋值(回顾下OC中KVC赋值 就理解了)
    
            这里forkey 一定要和B 属性名字一致 (也可以用@"_string")因为是属性
         */
    
        // 给B属性string  赋值
        [bViewController setValue:self.aTextField.text forKey:@"string"];
    
        [self.navigationController pushViewController:bViewController animated:YES];
    }
    
    @end
    

    B控制器.h文件:

    #import <UIKit/UIKit.h>
    
    @interface B_ViewController : UIViewController
    
    @property (nonatomic, copy) NSString *string;
    
    @end
    

    B控制器.m文件:

    #import "B_ViewController.h"
    
    @interface B_ViewController ()
    
    @end
    
    @implementation B_ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.title = @"B";
        self.view.backgroundColor = [UIColor whiteColor];
    
        self.view.backgroundColor = [UIColor whiteColor];
        UILabel *bLabel = [[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 200, 100, 30)];
    
        bLabel.layer.borderColor = [UIColor grayColor].CGColor;
        bLabel.layer.borderWidth = 1;
        [self.view addSubview:bLabel];
    
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-50, 280, 100, 30);
        [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [button setTitle:@"传值A" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
    
        // KVC 接收值
        bLabel.text = self.string;
    }
    
    - (void)buttonAction:(UIButton *)sender {
    
        [self.navigationController popToRootViewControllerAnimated:YES];
    }
    
    @end
    

好了,到此已经基本上介绍完页面传值了,相信你对页面传值已经有一定理解了吧,快去实践吧!