您的位置:首页 > 移动开发 > IOS开发

iOS 页面之间的传值方式

2017-04-01 10:48 141 查看
在iOS开发中,为了减少数据请求的次数和进行一些逻辑处理,常会在页面跳转的同时进行值得传递。常用的传值方式有:属性传值、通知传值、委托代理传值、Block传值、KVO传值。

在说传值之前,先来说一下页面的跳转。现有A、B两个页面,A页面有个跳转按钮,当点击按钮的时候执行push或者present操作,页面跳转到下一级页面B,这个跳转叫做正向跳转。当点击B页面中的返回按钮,页面返回到上一级页面A,这样的跳转叫做逆向跳转(反向跳转)。与之对应的传值就有了正向传值和逆向传值这两种逻辑形式。

在正向跳转的时候,要传递值到下一级页面,这个时候的传值叫做正向传值。在开发中,常用的正向传值方式是属性传值,因为这个方式是最简单方便的。当逆向跳转的时候,要传值到上一级页面,这个时候可以选择的方式就很多,可以是通知、代理、Block、KVO。但是具体选择哪一个要看具体情况而定。

首先,来看看属性传值:

属性,就是对象属性,也就是一个类中的成员属性,我们利用这个属性可以在页面跳转的时候进行值得传递。这里要注意的是,这个属性必须要对外开放的,也就是外部对象可以访问到这个属性,才可以进行属性传值。如何开放?很简单,就是在.h文件中去声明这个属性就可以对外开放。下面,用代码讲解:

AViewController.m中代码:

#import "AViewController.h"

#import "BViewController.h"

@interface
AViewController ()

{

    UIButton *button;

    UILabel *label;

}

@end

@implementation AViewController

- (void)viewDidLoad {

    [super
viewDidLoad];

    

    [self
setUI];

}

#pragma 创建视图

- (void)setUI{

    label = [[UILabel
alloc]initWithFrame:CGRectMake(100, 200, 200, 30)];

    label.text =
@"A页面要传递的值";

    label.font = [UIFont
systemFontOfSize:15];

    label.backgroundColor = [UIColor
yellowColor];

    [self.view
addSubview:label];

    

    button = [UIButton
buttonWithType:UIButtonTypeCustom];

    button.frame =
CGRectMake(100, 300, 200, 30);

    button.backgroundColor = [UIColor
blueColor];

    [button
setTintColor:[UIColor
whiteColor]];

    [button
setTitle:@"点击跳转"
forState:UIControlStateNormal];

    [button
addTarget:self
action:@selector(push)
forControlEvents:UIControlEventTouchUpInside];

    [self.view
addSubview:button];

}

#pragma 按钮点击事件,页面跳转

- (void)push{

   
//2、创建B控制器对象。

    BViewController *bVC = [[BViewController
alloc]init];

   
//3、使用对象调用对象属性,并给属性赋值。

    bVC.string =
label.text;

    //4、页面跳转

    [self.navigationController
pushViewController:bVC
animated:YES];

}

@end
BViewController.h中代码:

#import <UIKit/UIKit.h>

@interface BViewController :
UIViewController

//1、声明属性,用来接收传递的值

@property (nonatomic,
copy) NSString *string;

@end
BViewController.m中代码:

#import "BViewController.h"

@interface
BViewController ()

{

    UILabel *label;

}

@end

@implementation BViewController

- (void)viewDidLoad {

    [super
viewDidLoad];

    self.view.backgroundColor = [UIColor
grayColor];

    

    label = [[UILabel
alloc]initWithFrame:CGRectMake(100, 200, 200, 30)];

    //5、使用属性给label赋值

    label.text =
self.string;

    label.font = [UIFont
systemFontOfSize:15];

    label.backgroundColor = [UIColor
yellowColor];

    [self.view
addSubview:label];

}

@end

运行结果:


             


在上面的运行结果可以看到,A页面中label上的文字传递到了B页面中去显示。说明传值是成功的。现在在回来看看属性传值的步骤:

//1、声明属性,用来接收传递的值

@property (nonatomic, copy) NSString *string;

//2、创建B控制器对象。

BViewController *bVC = [[BViewController alloc]init];

//3、使用对象调用对象属性,并给属性赋值。

bVC.string = label.text;

//4、页面跳转

[self.navigationController pushViewController:bVC animated:YES];

//5、使用属性给label赋值

label.text = self.string;

上面的5个步骤就是属性传值的“公式”了,只需要子啊要接受传值的页面中先定义出一个对外开放的属性,然后再要传值的页面的页面跳转之前给要跳转对象的属性赋值就可以将值传递过去。

上面的属性传值只能用于正向传值,而不能用于逆向传值,因为在页面返回的时候是没有要返回页面的对象的,要是再创建一个上级页面进行跳转返回,那么就会出现循环引用的问题。在做逆向传值的时候,常采用的方式是另外的集中传值方式了:通知传值、委托代理传值、Block传值、KVO传值。

这几种传值,在前面的文章中都已经有了介绍,这里就不多说了。这里要说的是在传值的时候,具体去选择哪一种传值方式会更好。

首先是正向传值,这个当然是属性传值更好,更方便。逆向传值的时候,如何去选择?这是一个问题。

在选择之前,先来看看每种传值方式的优点有哪些:

通知传值:都知道,通知就是广播机制,既然是广播,那么就可以让很多的对象“听到”,这样的机制就使得通知在传值的时候,可以给很多对象传值,通知不去管有哪个对象接收,也不去管有多少个对象接收。只需要去发送通知就可以了,至于谁接收与发送通知的对象无关。这样的优点就使得通知的传值对象更广。所以,在使用的时候,可以在不知道有哪个对象要接收,也不知有多少个对象需要这个传值的时候使用。

委托代理传值:委托代理其实就是制定协议,然后遵守协议,最后实现协议方法取值的形式。这样的形式就是的有很强的针对性,要取值就必须要遵守协议并实现协议方法。所以,在开发中,常用来做定向定点的传值。这里的定向定点并不是说代理不能给很多对象传值,只是一般不这么做而已,因为很多对象都遵守协议实现代理,这样的代码会很乱。不如通知简单。

Block传值:代码块Block传值和代理传值差不多,都是用来做定向定点的传值。但是Block不需要去设置代理,不需要去设置协议。相比较于代理,代码方面会减少很多。但是它也有个缺点,就是如果代码中有大量的传值操作,Block使用太多会使得代码看着很乱不利于管理,而却使用不当还容易引起内存泄漏。所以Block的使用要适当。

KVO传值:KVO的原理是监听,它监听到对象的属性发生变化后就会做出相应,在相应的同时可以实现值得传递,这样的机制和通知差不多,用来“多方面的”传值。

从上面的介绍来看,

通知和KVO常用来做不知对象的传值,比如:

现在有一个开关,当开关开启的时候,传值1,加载网络数据,当开关关闭时,传值0,加载本地数据。这个时候我们就不知道有多少地方要接收0和1。所以适用通知或者KVO就很合适,不需要去管其他的,只负责把值传出去。谁要接收谁就接收通知或者添加观察者就好了。

代理和Block常用来做定点传值,比如:

现在页面上有个选择地址的栏目,点击这个栏目跳转到下一级页面中去选择国家,当点击选中的国家后,页面返回,并将选中的国家的名称传递回来。这样的需求,使用代理或者Block就更合适,因为只有在这里使用到传值,针对性很强。

在开发中,不同控制器之间的传值是很重要的,传值方式的选择可以方便代码的编写。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: