IOS常用的传值方式

IOS项目开发中,经常需要在不同的控制器之间跳转时进行传值操作,传值方式按传递的方向分为正向传值和逆向传值,正向传值比较好理解,就比如A控制器Push跳转至B控制器时,在A控制器中获取到B控制器的实例化对象,对B控制器的属性进行赋值,当控制器完成跳转后,就完成了值的传递。而逆向传值是B控制器Pop到A控制器时,对A控制器的某个属性进行赋值,虽然在B控制器中可以获取到A控制器的实例化对象,但是不能像正向传值那样,直接对A控制器的属性进行赋值。而是通过三种常用的逆向传值方式进行传值,即代理、通知、Block。

以下这个demo为不同传值方式的传值效果:

比较直观的理解三种传值方式的不同,讲上述demo的代码进行一下基本的分析展示,正向传值为A控制器Push到B控制器:

1.首先搭建传值界面,包括两个控制器和相关的传值按钮控件(此处通过StoryBoard创建),同时设置两个传值的字符串属性:titleStr 和color:

//A控制器设置控件属性
#import "FirstViewController.h"
@property (weak, nonatomic) IBOutlet UIButton *firstBtn;
@property (weak, nonatomic) IBOutlet UIButton *showSecBtn;
@property (weak, nonatomic) IBOutlet UIButton *SecresultBtn;

//B控制器设置控件属性
#import "SecondViewController.h"
@property (weak, nonatomic) IBOutlet UIButton *revieVeBtn;
@property(nonatomic,copy) NSString *titleStr;
@property(nonatomic,strong) UIColor *color; 

2.顺传,在A控制器中对B控制器中两个属性进行赋值:

    //实例化B控制器
    SecondViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"CC"];
    //讲titleStr和color设置为B控制器的私有属性,在A控制器中使用KVC进行赋值
    [vc setValue:self.firstBtn.titleLabel.text forKey:@"titleStr"];
    [vc setValue:self.firstBtn.backgroundColor forKey:@"color"];
    //跳转控制器
    [self.navigationController pushViewController:vc animated:YES];

3.代理逆传,在B控制器中调用A控制器中定义的赋值方法

//1.1 在B控制器中添加代理协议
@protocol SecondViewControllerDelegate <NSObject
//设置代理方法(设置可选或必选)
-(void)changeThestatus:(UIButton*)ban;
//设置代理属性
@property(nonatomic,weak)id<SecondViewControllerDelegate> 

//1.2 在B控制器中调用代理方法
    if ([self.delegate respondsToSelector:@selector(changeThestatus:)]) {
        [self.delegate changeThestatus:sender];
}

//1.3 在A控制器中添加代理协议
@interface FirstViewController ()<SecondViewControllerDelegate>

//1.4 在A控制器中实例化B控制器
SecondViewController *secVc = [self.storyboard instantiateViewControllerWithIdentifier:@"second"];

//1.5 设置代理对象
secVc.delegate = self;

//1.6  定义代理实现方法
-(void)changeThestatus:(UIButton*)btn{
    [self.showBtn setBackgroundColor:btn.backgroundColor];
    [self.showBtn setTitle:btn.titleLabel.text forState:UIControlStateNormal];
}

4.通知逆传

//2.1 在B控制器中发送通知(在跳转控制器的方法中)
//object参数为包含传递值的对象或值本身
[[NSNotificationCenter defaultCenter]postNotificationName:@"change" object:sender];

//2.2 在A控制其中注册通知观察者
//必须注意在注册观察者要保证观察者的注册先于通知发送,否则将收不到通知,本例中注册观察者放在A控制器跳转到B控制器的方法中,在A控制器跳转到B控制器后,B控制器往回跳转A控制器时观察者已经生成。
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(changeShow:) name:@"change" object:nil];

//2.3 定义观察者的实现方法
-(void)changeShow:(NSNotification*)notification
    UIButton *btn = notification.object
    [self.showBtn setBackgroundColor:btn.backgroundColor]
    [self.showBtn setTitle:btn.titleLabel.text forState:UIControlStateNormal];

//2.4 注销观察者
-(void)dealloc{

    [[NSNotificationCenter defaultCenter]removeObserver:self];
}

5.Block逆传,通过在B控制器中设置一个Block类型的属性,在B控制器的跳转方法之前进行回调,在A控制器中定义Block的实现:

//3.1 在B控制器中声明一个Block属性
typedef void(^myBlock)(UIButton*btn);
@property(nonatomic,copy)myBlock Nblock;

//3.2 在B控制器跳转A控制器的方法中回调Block,或者是将这个属性作为方法参数,在方法中回调这个Block
    if (self.Nblock) {
        self.Nblock(sender);
}

//3.3 在A控制器实例化B控制器的代码后,通过B控制器获取到Block属性,对Block进行实现定义,在此书对A控制器中需要传值的对象进行赋值
SecondViewController *secVc = [self.storyboard instantiateViewControllerWithIdentifier:@"second"];
    secVc.Nblock = ^(UIButton* btn){
        [self.showBtn setBackgroundColor:btn.backgroundColor];
        [self.showBtn setTitle:btn.titleLabel.text forState:UIControlStateNormal];
};

通过以上代码,我们可以了解到不同传值方法的基本用法,对于逆传的三种方法,有着各自的优缺点和应用场景,下面对这三种方式进行一下简单的分析:

第一就是代理,这也是很常用的方式,特点是一对一的形式,而且逻辑结构非常清晰,就是当前类中完成不了的事情,叫给另外一个类去完成,当然前提是在另外一个类中可以获取到当前类。如在tableviewcell中有一个btn按钮是需要刷新tableview 数据的,此时在cell中就可以将tableview设置为代理对象,在tableview中获取到cel,cell.delegate = tableView设置代理对象完成后,定义代理方法的实现就可以完成,

当然这里面有一些细节,包括协议定义时,要用到关键字@required,和@optional来明确代理是否必须实现某些方法,代理的类型需用id类型(weak修饰),并写明要遵守的协议,并在在调用代理方法的时候需要判断代理是否实现该方法;

第二就是通知,通知的优点很明显,他是一对多的形式,而且可以在任意对象之间传递,不需要二者有联系。通知需要的注意点就是注册的通知中心需要手动移除,不然除了性能的问题还会有其他的问题出现,比如说一个控制器消失了之后还有因为某些事件而发出通知,造成不想要的结果。但是一个程序中如果使用过多的通知后,会造成业务逻辑的可读性降低,理解起来没有代理那么清晰;

第三就是block了,这是苹果后来才加入的,也是目前开发比较常用的一种方式,功能比较强大。它的最大特点就是回调,回调的意思简单的理解就是,将方法的申明、调用与方法实现分开,将实现部分写在需要传值的控制器中。而且回调时可以传入参数, block本身可以封装一段代码,因此在定义实现时,可以在实现部分写入需要执行的代码。可以说block简化了代理方法,使用起来更灵活、简便。通常用作方法的参数,在方法中进行回调。

由于本人水平有限,以上有误指出,请大家不吝赐教。

时间: 2025-01-02 13:40:10

IOS常用的传值方式的相关文章

iOS常用的存储方式介绍

在iOS App开发过程中经常需要操作一些需要持续性保留的数据,比如用户对于App的相关设置.需要在本地缓存的数据等等.本文针对OC中经常使用的一下存储方式做了个整理. 常用的存储工具/方式: NSUserDefaults类 Plist文件 解归档 手动存放沙盒 // sqlite CoreData 第三方数据存储框架 1. NSUserDefaults 一般对于一些基本的用户设置,因为数据量很小,我们可以使用OC语言中的 NSUserDefaults类来进行处理.使用方法很简单,只需要调用类中

iOS 五种传值方式

1.属性传值和代理传值 #import <UIKit/UIKit.h> #import "SecondViewController.h" @interface ViewController : UIViewController<UITextFieldDelegate,postValuedelegate> @property (nonatomic ,strong) UITextField *textfld; @property (nonatomic ,strong

iOS开发-各种传值方式

属性传值 将A页面所拥有的信息通过属性传递到B页面使用 B页面定义了一个naviTitle属性,在A页面中直接通过属性赋值将A页面中的值传到B页面. A页面DetailViewController.h文件 #import <UIKit/UIKit.h> #import "DetailViewController.h" @interface RootViewController :UIViewController<ChangeDelegate> { UITextF

ios常见的页面传值方式

iOS页面间的传值细分有很多种,基本的传值方式有三种:委托Delegate传值.通知NSNotification传值.Block传值,其他在项目中可能会遇到的还有:UserDefault或文件方式传值.单例模式传值.通过设置属性传值,再有其他的传值方式没有遇到使用过在此不做说明.场景适合,自己使用舒服就是好的方式. 在iOS开发的过程中,常见的页面跳转传值方式大致可以分为两种,现归纳总结一下: 第一种:OneViewController页面跳转到TwoViewController页面(即顺传)

iOS页面间传值的六种方式

一般ios页面间的传值方式分为6种:1.属性传值:2.block:3.delegate:4.UserDefault:5.单例:6.通知. 0&1.block 先说我最常用的block吧,属性传值就很简单了,主要用于顺传,我们在这里包括下面都主要讲逆传.属性传值放在block里一起写了. 下面上代码: //secondVc.h typedef void (^TestBlock) (NSString *str); @interface ATNextViewController : UIViewCon

iOS 页面间几种传值方式(属性,代理,block,单例,通知)

iOS 页面间几种传值方式(属性,代理,block,单例,通知) 姜糖水 2015-05-03 52 阅读 iOS 移动开发 第二个视图控制器如何获取第一个视图控制器的部分信息 例如 :第二个界面中的lable显示第一个界面textField中的文本 这就需要用到属性传值.block传值 那么第一个视图控制器如何获的第二个视图控制器的部分信息 例如:第一个界面中的lable显示第二个界面textField中的文本 这就需要使用代理传值 页面间传值有八大传值方式,下面我们就简单介绍下页面间常用的五

iOS页面间传值的方式(Delegate/NSNotification/Block/NSUserDefault/单例)

iOS页面间传值的方式(NSUserDefault/Delegate/NSNotification/Block/单例) 实现了以下iOS页面间传值:1.委托delegate方式:2.通知notification方式:3.block方式:4.UserDefault或者文件方式:5.单例模式方式:6.通过设置属性,实现页面间传值 在iOS开发中,我们经常会遇到页面间跳转传值的问题,现归纳总结一下: 情况1:A页面跳转到B页面 方法: 在B页面的控制器中,编写对应的属性,在A页面跳转到B页面的地方,给

iOS 页面间几种传值方式(属性,代理,block,单例,通知)

第二个视图控制器如何获取第一个视图控制器的部分信息 例如 :第二个界面中的lable显示第一个界面textField中的文本 这就需要用到属性传值.block传值 那么第一个视图控制器如何获的第二个视图控制器的部分信息 例如:第一个界面中的lable显示第二个界面textField中的文本 这就需要使用代理传值 页面间传值有八大传值方式,下面我们就简单介绍下页面间常用的五种传值方式: (一)属性传值 第二个界面中的lable显示第一个界面textField中的文本 首先我们建立一个RootVie

iOS学习之六种传值方式

iOS页面传值方式 应用于: 两个互动的界面:1)页面一跳转到页面二,页面一的textField的值传给页面二的label.2)A页面跳转到B页面,B页面再跳转回A页面(注册页面跟登录页面) 两个不互动的两个界面:数据持久层跟表示层的数据交互. 几种传值方式: 属性传值  委托delegate方式 通知notification方式 block方式 单例模式方式 UserDefault或者文件方式 1.属性传值(顺传): 需要定义一个公开的属性 需要一个你需要传值的对象 进行属性赋值 实现:A.B