当前位置: 首页 > news >正文

OC—多界面传值

注:有关协议传值与属性传值的内容,在前面的博客中有介绍,这里就不在赘述了

通知传值

简介:通知传值是一种跨模块的通信机制,允许对象在不直接引用对方的情况下传递数据。通知传值使用NSNotificationCenter,它是观察者的一种实现方式,通知者的发送方负责发送NSNotification,通知的接收注册方注册成为观察者,处理通知

NSNotification类:(通知的载体)

@property (readonly, copy)NSString* name;//通知名称
@property (nullable, readonly, retain)id object;//发布者对象
@property (nullable, readonly, copy)NSDictionary* userInfo;//传递的参数

Notificationcenter类的核心方法:

+ (NSNotificationCenter* )defaultCenter;//获取全局通知中心- (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSString *)aName object:(nullable id)anObject;//添加观察者- (void)postNotificationName:(NSString *)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;//发布通知- (void)removeObserver:(id)observer;//移处观察者

使用步骤:

1.发送通知:

NSDictionary* userInfo = @{@"notice" : @(1)};[[NSNotificationCenter defaultCenter] postNotificationName:@"note" object:nil userInfo:userInfo];

注意:userInfo是用来传递数据得,需要用字典类型

2.监听通知:注册观察者

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeColor:) name:@"note" object:nil];

3.接收通知:回调方法

- (void)changeColor:(NSNotification* )notification {NSDictionary* dict = notification.userInfo;NSNumber* num = dict[@"notice"];if ([num intValue]) {self.view.backgroundColor = [UIColor blackColor];}
}

4.移除监听者:释放资源

在dealloc中移除监听者非常重要,防止内存泄露或崩溃:

典型应用场景:

登陆成功后,刷新首页

设置页面更改后,通知其他页面刷新UI

用户退出登录,用户清理数据

  • 通知传值使用限制,适用范围

1.符合NSCoding协议的对象,对于自定义对象,需要实现NSCoding协议

2.必须手动移除通知观察者,避免内存泄漏,(原因:通知中心持有观察者对象的强引用)

3.传递的userInfo中的对象在通知发生后被系统自动释放,如果需要保留,可以copy一个副本

4.通知名称具有全局唯一性

  • 实现NSCoding协议指南

1.NSCoding是OC中实现对象序列化(编码与解码)的核心协议,用于将对象转换为字节流(归档)或从字节流恢复对象(解档)

浅浅学习一下解档与归档的内容:

是一种用于对象序列化和反序列化的重要机制,核心目的是将对象转换为可存储或传输的字节流,以及将字节流还原为对象

NSKeyedArchiver与NSkeyedUnarchiver:

NSKeyedArchiver:归档工具类,通过键值对将对象编码为二进制数据

NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:myObject];
[archivedData writeToFile:filePath atomically:YES];

NSkeyedUnarchiver:解档工具类,用于从二进制数据中解码对象

NSData *archivedData = [NSData dataWithContentsOfFile:filePath];
MyObject *decodedObject = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];

这个过程必须实现两个方法:

encodeWithCoder:将对象属性编码到归档中

initWithCoder:从归档中解码并初始化对象

@interface User : NSObject <NSCoding>
@property (nonatomic, copy) NSString *name;
@end@implementation User
- (void)encodeWithCoder:(NSCoder *)coder {[coder encodeObject:self.name forKey:@"name"];
}
- (instancetype)initWithCoder:(NSCoder *)coder {self = [super init];self.name = [coder decodeObjectForKey:@"name"];return self;
}
@end

KVO传值

KVO是观察者模式的一种具体实现,是apple提供的一套通知机制,允许对象监听另一个对应特殊属性的改变,并在改变时接收到该事件,一般继承自NSObject的对象都是默认支持KVO的。

KVO(Key-Value-Observing),即观察关键字值的变化,首先在子页面中声明一个待观察的属性,在返回主页面之前修改该属性的值。在主页面中提前分配并初始化子页面,并且注册对子页面中对应属性的观察者,在从子页面返回主页面之前通过修改观察者属性的值,在主页面中就能自动检测到这个改变,从而读取子页面数据。KVO只对属性发生作用。

底层原理:(基于OC的动态运行时特性)

1.动态创建子类:当对某个对象添加KVO观察时,系统会动态生成一个该对象类的子类,名为NSKVONotifying_原类名

2.重写setter方法:子类会重写被观察属性的setter方法。在方法中插入通知发送逻辑

3.isa混写:系统会将原对象的isa指针指向这个动态子类。使原对象实际成为子类的实例

4.通知触发:当调用setter方法时,子类会先调用父类(原类)的setter,再通知所有观察者

@interface NSKVONotifying_Person : Person
- (void)setName:(NSString *)name;
@end@implementation NSKVONotifying_Person
- (void)setName:(NSString *)name {// 1. 调用原类的setter[super setName:name];// 2. 通知所有观察者属性已变更[self willChangeValueForKey:@"name"];[self didChangeValueForKey:@"name"];
}
@end
  • 传递方向:从前向后

KVO的基本使用流程:

1.注册观察者:监听某个属性

[self.person addOserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOldcontext:nil];

参数讲解:

self.person:被观察者对象

“name”:被观察者的属性名

options:监听新值、旧值等

选择监听的返回值的类型:

enum {NSKeyValueObservingOptionNew //接收方法中使用change参数传入变化后的新值NSKeyValueObservingOptionOld //接收方法中使用change参数传入变化前的旧值NSKeyValueObservingOptionInitial //change参数内容会包含新值NSKeyValueObservingOptionPrior //如果加入这个参数,接收方法会在变化前后分别调用一次,共两次,变化前的通知change参数
}

2.实现回调方法:监听属性变化

(2). 接受通知,使用方法observeValueForKeuPath:ofObject:change:context:

(3). 删除KVO,与通知传值相同

- (void)dealloc {[self removeObserver:self forKeyPath:@"name"];
}
  • 使用注意与适用范围

1.KVO基于KVC实现,仅能观察通@property声明的属性,普通的成员变量无法被观察

2.基本类型需要NSNumber包装,不支持直接观察C结构体(如CGPoint),需要封装为对象属性

@property (nonatomic, assign) int age;  //KVO会自动包装为NSNumber

3.动态属性(@dynamic):

若属性声明为@dynamic,需要手动实现KVO通知:

@interface DynamicPropertyClass : NSObject
@dynamic customProperty;
@implementation DynamicPropertyClass
- (void)setCustomProperty:(id)value {[self willChangeValueForKey:@"customProperty"];[self didChangeValueForkey;@"customProperty"];
}
@end

4.若多个KVO观察使用同一回调,需要通过context区分

Block传值

简介:

适用于后一个界面向前一个界面传值

Block 传值是一种反向数据传递机制,核心流程如下:

  1. 定义 Block 类型:在数据接收方(通常是子视图 / 子控制器)定义一个 Block 属性。
  2. 设置 Block 实现:在数据发送方(通常是父视图 / 父控制器)创建子对象时,为其 Block 属性赋值(实现数据处理逻辑)。
  3. 调用 Block:当子对象需要传递数据时,调用该 Block 并传入数据。

数据流向:子对象 → Block → 父对象

步骤:

1.在后一个页面定义一个Block属性

#import "SecondView.h"
@property (nonatomic, copy) void(^reutnblock)(NSString* str);

2.设置一个事件来触发返回上一级视图的时候,使用第一步定义的Block,把需要传递的值放在^Block内

#import "SecondView.h"
-(void)pressbutton{self.reutnblock(self.label.text);[self.navigationController popViewControllerAnimated:YES];
}

3.在前一个页面跳转到后一个页面的事件函数中,调用后一个页面的Block属性

#import "FirstView.h"
-(void)pressbutton {secondViewController* second = [[secondViewController alloc] init];second.reutnblock = ^(NSString * _Nonnull str) {self.label.text = str;};[self.navigationController pushViewController:second animated:YES];
}
http://www.lryc.cn/news/573820.html

相关文章:

  • JAVA集合篇--深入理解ConcurrentHashMap图解版
  • Java面试复习指南:Java基础、面向对象编程与并发编程
  • 【论文阅读】 智能用户界面的用户接受度研究——以旋翼机飞行员辅助系统为例( Miller, C.A. Hannen, M.D. in 1999)
  • uni-app项目实战笔记21--uniapp缓存的写入和读取
  • 【代码解析】opencv 安卓 SDK sample - 1 - HDR image
  • Spring JDBC配置与讲解
  • Python 使用Gitlab Api
  • Kafka与Zookeeper在linux上的下载记录
  • LLMs之Embedding:Qwen3 Embedding的简介、安装和使用方法、案例应用之详细攻略
  • ms-swift 部分命令行参数说明
  • OpenGL ES 中的材质
  • AI 辅助生成 Mermaid 流程图
  • 华为公布《鸿蒙编程语言白皮书》V1.0 版:解读适用场景
  • Android14 app被冻结导致进程间通信失败
  • 电脑商城--购物车
  • 【C++】C++枚举、const、static的用法
  • Python炫酷星空
  • 前端的跨域问题
  • Java Stream流
  • 量化-因子处理
  • 飞轮储能辅助双馈风机参与电力系统一次调频的仿真模型研究
  • 半导体二极管
  • work遇到的状态码
  • 跨平台开发flutter初体验
  • 华为云Flexus+DeepSeek征文|华为云 Dify 高可用部署教程:CCE 容器集群一键构建企业级智能应用
  • 登录拦截功能实现 -瑞吉外卖笔记
  • Windows 后渗透中可能会遇到的加密字符串分析
  • 等等等等等等
  • PostgreSQL全栈部署指南:从零构建企业级高可用数据库集群
  • pyqt f-string