IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> iOS—多界面传值 -> 正文阅读

[移动开发]iOS—多界面传值

前面我们学习了协议传值与属性传值,协议传值里面关键点在于确实不要忘了在推出后页面的时候将后页面设置代理

backViewController.delegate = self;

后页面的数据通过将此代理作为对象,调用协议的对象方法用来传值,要传的数据会作为协议的对象方法的参数传入该协议方法,再在前页面用前页面的变量去接收协议方法的参数,即可在前页面的任意地方使用后页面传过来的数据,配合属性传值可以达到前后页面数据的互通,但这样很不方便,传一个数据要用到两种传值方式,光是听一下,血压都上来了。
我们的传值方法很多,我来介绍一下其他传值方法,相信在你看完以后对于传值方法会有更深的理解。
如果对于协议传值和属性传值还不熟悉的推荐看一下我的上一篇关于协议传值和属性传值的介绍。
协议传值与属性传值

block传值

block传值和协议传值比较像,都是从后页面传数据给前页面

block介绍

在了解block传值之前,我们还是先来看一下block的介绍
Block是带有自动变量的匿名函数,是C语言的一个扩充功能。Block本质上也是一个OC对象。
block其本质和变量相同,只不过block存储的数据是一个函数体,你可以像调用其他标准函数一样,传入参数,并切获得返回值。
传值:只要能拿到对方就能传值
顺传:给需要传值的对象,直接定义属性就能传值
逆传:用代理,block,就是利用block去代替代理

使用block传值

我们既然知道其方法和协议传值类似(反向传值),我可以借鉴,协议传值的思路去理清block传值的关系。
我们需要在后页面的.m文件中去定义一个block属性。

@property (nonatomic, copy) void (^dataBlock) (NSString* textOfData);

我这里想传一个NSString类型的变量,我可以在后页面的.m文件中再定义一个NSString类型变量

@property (nonatomic, strong) NSString* myTextOfData;

既然是后页面向前页面传值,那么和协议传值类似,在由后页面推向前页面的button事件函数中可以添加此block

- (void)pressSecondButton {
    
    _dataBlock (myTextOfData);
    [self dismissViewControllerAnimated:NO completion:nil];
}

接下来在前页面跳向后页面的Button事件函数中调用此block(dataBlock)

- (void)pressFirstButton {
    BackViewController* backViewController = [[BackViewController alloc] init];
    backViewController.block = ^(NSString* textOfData) {
        self.TitleLabel.text = textOfData;
    };
    backViewController.modalPresentationStyle = UIModalPresentationFullScreen;
    [self presentViewController:nextViewController animated:NO completion:nil];
}

和协议传值类似,数据都是以一个函数参数的方式传过去的,学习过协议传值后,再去理解block传值就会方便很多。
接下来看看KVO传值

KVO传值

KVO介绍

在了解KVO传值前,按照惯例还是先来看看什么事KVO吧,家人们。
KVO是(Key - Value Observing)的简称,这是一种观察者模式的应用。当观察者将被观察者的某个属性设置为观察的对象时,若被观察的该属性值发生变化时,就会触发观察者对象所实现的KVO接口方法,从而达到通知观察者的目的。

注意:由于KVO通知是通过重写属性的setter方法实现的,所以必须通过属性的setter方法来改变属性值时KVO通知才会被触发,如果通过属性的"_"成员变量来修改属性值时是不会触发KVO的。
KVO只是监听setter方法,例如像可变数组添加元素的方法(addObject)它不属于setter方法,所以即使你向数组中add多少个元素也不会有监听反应。

已经学了那么多传值方法了,对于前后页面的具体数据我就不展示了,这里只关注函数里面的调用方案

使用KVO传值

既然是观察者模式,那我们势必是要去注册一个人去当这个观察者的,让他去盯着被观察者,被观察者的属性值发生变化的时候,我们观察者肯定也是第一个收到,该项变化的属性值的。

注册观察者

  • (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
    observer:观察者对象; KeyPath:要监测的键路径;options:需要监测的选项;context:上下文用来区分消息;
    移除观察者
  • (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
  • 一定要在观察者消失之前调用removeObserver,否则会导致Crash。
    监听回调
    – (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change context:(nullable void *)context;
    这里先简单看看这三个函数,这几个是使用KVO传值的关键
    我们在使用KVO传值的时候,可以先建立一个NSObject的子类ObserverMan.h
    其中声明一个属性
    @property (nonamtic, assign) int number;
    我们在一个viewcontroller中添加新建的子类的头文件,并为其设置一个属性名为 observerSon
    在其实现文件中去初始化我们的新观察者并为其注册观察者身份
 _observerSon = [[ObserverMan alloc] init];
    //注册监听者
    [_observerSon addObserver:self forKeyPath:@"number" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

我们可以设置一button去更改这个numer

- (void)addNumber:(UIButton*)button {
    static int a = 0;
    //改变其中的number的值,会调用监听方法
    _observerSon.number = a++;
}
//监听方法,当KVO事件到来时会调用这个方法,如果没有实现会导致Crash
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    //通过调用监听事件,来改变_label显示的内容
    NSString *string = [[NSString alloc] initWithFormat:@"number:%d", _observerSon.number];
    _label.text = string;
    //在控制器中输出改变前的旧值和改变后的新值
    NSLog(@"old number: %@ --- new number: %@", [change valueForKey:@"old"], [change valueForKey:@"new"]);
}

//在不使用的时候移除监听
- (void)dealloc {
    [_observerSon removeObserver:self forKeyPath:@"number"];
}

我们现在已经了解了KVO的传值方式,接下来简单一说多界面中使用KVO传值

我们先创建一个后页面
为后页面创建一个按钮事件

//按钮事件,因为KVO是监听setter事件所以这里的content必须要用self.content点语法来访问,否则无法传回数据
- (void)pressBack:(UIButton*)button {
    self.content = _textField.text;
    //content为自己定义的NSString属性
    [self dismissViewControllerAnimated:YES completion:nil];
}

接下来我们需要在前页面的头文件中去定义后页面的属性

@property (nonatomic, strong) BackViewController *back;

在推出后页面的按钮事件函数中初始化当前视图属性
并且为其注册观察者,主要的参数forKeyPath:@“content”
(此处的content为后页面中自定义的属性content)

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"content"]) {
        id value = [change valueForKey:@"new"];
        _label.text = value;
    }
}

记住在不用的时候销毁观察者,不能让他知道的太多了

通知传值

通知传值的介绍

首先通知传值也是逆向传值的一种,我们必须要 知道通知传值是谁要监听值的变化,谁就注册通知 特别要注意,通知的接受者必须存在这一条件 。可以跨越多个页面传值

  1. 注册通知
  2. 通知中心发送通知消息,其中name(通知名)前后要保持一致性
  3. 实现通知内部的方法,并实现传值
  4. 消息发送完之后,要移除通知

使用通知传值

在前页面注册通知
第三个参数的事件名,系统使用此事件名来区分不同的事件

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(message:)name:@“message” object:nil];

在前页面的实现文件中,添加函数,设置接受到通知的事件

- (void)message:(NSNotification *)text {


    _textOfLabel.text = text.userInfo[@"textOfData"];
}

在前页面的dealloc将通知移除掉
移除通知:removeObserver:和removeObserver:name:object:
其中,removeObserver:是删除通知中心保存的调度表一个观察者的所有入口,而 removeObserver:name:object:是删除匹配了通知中心保存的调度表中观察者的一个入口。
注意参数removeObserver为要删除的观察者,一定不能置为nil。

- (void)dealloc {
- 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"message" object:self];
}

在后页面中建立一个通知中心,通过此通知中心来发送通知,将要传输的值作为object的值传给前页面

[[NSNotificationCenter defaultCenter] postNotificationName:@"message" object:nil userInfo:_dictionary];
 //postNotificationName:之后的参数就是这个通知的名字,要和要和接收者中的名字一样,才能让接收者正确接收。     
 //object:接收对象。
 //userInfo: 携带的参数,为字典类型的数据,在例子中我携带了一个字典,因为有时候我们要传递的参数不只是一个,所以把东西全部放在通知里面,在接收者中,根据字典里面的键来取出里面的值。

发送通知,其中的name填写第一界面的name, 系统知道是第一界面来相应通知, object就是要传的值。 userInfo是一个字典, 如果要用的话,提前定义一个字典, 可以通过这个来实现多个参数的传值使用。

	//添加 字典,将label的值通过key值设置传递
    NSDictionary *zidian =[[NSDictionary alloc]initWithObjectsAndKeys:self.firstTextField.text,@"textOfData", nil];
    //创建通知
    NSNotification *notification =[NSNotification notificationWithName:@"message" object:nil userInfo:zidian];
    //通过通知中心发送通知
    [[NSNotificationCenter defaultCenter] postNotification:notification];


我目前所了解到的就这么多,个人学识有限,还望各位大佬指正,学习还是要再接再厉,多努力一点,大概能多幸运一点,我们下次再见。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 19:17:25  更:2022-08-19 19:21:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 5:15:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码