关于NSNotificationCenter

Published 2025-03-24 20:58 1376 words 7 min read

前端项目通过bridge获取客户端资源,客户端直接返回response对象常用代码模板1——基础算法常用代码模板2——数据结构统计iOS工程代码行数高数概念、公式、定理Objective-C 语法 3Objective-C 语法 2Objective-C 语法 1UIViewController 的生命周期UITableview调用reload方法时抖动问题UILabel中文带行间距的处理,限制行数,计算高度等UIButton扩大点击范围以及关于响应者链条的思考UIApplicationSwiftUI基本控件iPhone6 Plus上面神秘的缝隙iPhone 刘海机型UI适配(X、Xs、Xs Max、Xr)iOS:如何在UITableView调用reloadData刷新结束后再同步执行后续操作iOS 截取整个 scrollview 图片iOS 关于 UITextField 的字数限制Objective-C 中禁止调用指定的方法objc源码分析-runtime-classObjective-C Type EncodingsObjective-C:为什么分类中不能直接添加属性OC优缺点以及常见bugruntime——运行时简单使用当对象接收到不能处理的消息时调用的方法浅谈iOS中的weak为 UIControl 实现线程安全的 Block 事件扩展:原理与实践OC单例宏iOS常用数据类型转换OC中nil 、NULL、 Nil 、NSNull的区别Description方法和NSLog函数Block in Objective-CiOS自动化埋点的实现iOS平台编译Ogre游戏引擎库iOS:特殊符号大全iOS 网络小结iOS 沙盒与 BundleiOS 框架学习-AsyncSocketNSString的各种处理Swift Module 如何被全局引用CocoaPods组件化——OC/Swift动静态库混用COCOAPODS技巧-创建私有仓库关于NSNotificationCenter数据结构与算法解析习题2.23数据结构与算法解析习题2.19数据结构与算法解析习题2.16数据结构与算法解析习题2.14数据结构与算法解析习题2.13数据结构与算法解析习题2.12数据结构与算法解析习题2.11:二分查找数据结构与算法解析习题2.10:霍纳法则(Horner's rule)数据结构与算法解析习题2.7数据结构与算法解析习题1.3数据结构与算法解析习题1.2数据结构与算法解析习题1.1LeetCode 486 Predict the Winner(预测赢家)LeetCode 398 随机数索引LeetCode 106 Construct Binary Tree from Inorder and Postorder Traversal(由中序和后序遍历建立二叉树)LeetCode 70 爬楼梯(青蛙跳台阶)LeetCode 8 String to Integer (atoi)LeetCode 6 ZigZag Conversion(Z字转换)LeetCode 5 Longest Palindromic Substring(最长回文字串)iOS脚本打包 ipa(.app转.ipa)《什么是数学 》习题 第一章 补充《什么是数学 》习题 第一章 2 数系的无限性 数学归纳法《什么是数学 》习题 第一章 1 整数的计算Vue 的一些指令和缩写
This post is not yet available in English. Showing the original.
通知(NSNotification) 一个完整的通知一般包含3个属性: - (NSString*)name; // 通知的名称- (id)object; // 通知发布者(是谁要发布通知)- (NSDictionary*)userI

通知(NSNotification)

一个完整的通知一般包含3个属性:

- (NSString*)name; // 通知的名称
- (id)object; // 通知发布者(是谁要发布通知)
- (NSDictionary*)userInfo; // 一些额外的具体信息

初始化一个通知(NSNotification)对象

+ (instancetype)notificationWithName:(NSString*)aName object:(id)anObject;
+ (instancetype)notificationWithName:(NSString*)aName object:(id)anObject userInfo:(NSDictionary*)aUserInfo;
- (instancetype)initWithName:(NSString*)name object:(id)object userInfo:(NSDictionary *)userInfo;

发布通知方法

通知中心(NSNotificationCenter)提供了相应的方法来帮助发布通知

如果发布通知的方法在那一条线程上,则监听通知的对象调用的方法在会在这个线程上运行

所以:

如果在异步线程发的通知,那么可以执行比较耗时的操作;

如果在主线程发的通知,那么就不可以执行比较耗时的操作

// 发布一个notification通知,可在notification对象中设置通知的名称、通知发布者、额外信息等
- (void)postNotification:(NSNotification*)notification;

// 发布一个名称为aName的通知,anObject为这个通知的发布者
- (void)postNotificationName:(NSString *)aName object:(id)anObject;

// 发布一个名称为aName的通知,anObject为这个通知的发布者,aUserInfo为一些额外信息
- (void)postNotificationName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;

注册通知监听器

通知中心(NSNotificationCenter)提供了相应的方法注册监听器(Observer)来监听通知的发布:

// observer:监听器,即谁要接收这个通知
// aSelector:收到通知后,回调监听器的这个方法,并且把通知对象当做参数传入
// aName:通知的名称。如果为nil,那么无论通知的名称是什么,监听器都能收到这个通知
// anObject:通知发布者。如果为anObject和aName都为nil,监听器都收到所有的通知
- (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject;

// name:通知的名称
// obj:通知发布者
// block:收到对应的通知时,会回调这个block
// queue:决定了block在哪个操作队列中执行,如果传nil,默认在当前操作队列中同步执行
- (id)addObserverForName:(NSString *)name object:(id)obj queue:(NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *note))block;

取消注册通知监听器

通知中心不会保留(retain)监听器对象,在通知中心注册过的对象,必须在该对象释放前取消注册。否则,当相应的通知再次出现时,通知中心仍然会向该监听器发送消息。因为相应的监听器对象已经被释放了,所以可能会导致应用崩溃

通知中心提供了相应的方法来取消注册监听器

- (void)removeObserver:(id)observer;
- (void)removeObserver:(id)observer name:(NSString *)aName object:(id)anObject;

示例

一个朋友说看了我这篇还是该不懂还是不懂,感觉还是放个例子上来好一些,果然需求是技术进步的动力

首先要给通知起一个名字

最好用字符串常量,或者用宏也可以,这样可以保证发送和监听的是同一个通知

// 字符串常量
// 头文件中
extern NSString *const NotifationTest;

// 实现文件中
NSString *const NotifationTest = @"notificationTest";

// 或者直接用宏
#define NOTIFICATION_TEST @"notificationTest"

注册监听

给想要接受到通知的对象注册监听,这样就可以收到其他对象发的通知了,通知是可以重复注册的,每次多一次注册就会多收到一次通知,所以尽量在只执行一次的方法中注册,比如控制器的viewDidLoad方法中

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fuck) name:NotifationTest object:nil];

发送通知后,监听者会受到通知然后调用fuck方法 ! 😄

发送通知

发送通知就很简单了,想法通知的时候只需要post一下就好了

[[NSNotificationCenter defaultCenter] postNotificationName:NotifationTest object:nil];

移除通知

监听器被销毁了一定要记得取消注册…

// 一般在监听器销毁之前取消注册(如在监听器中加入下列代码):
- (void)dealloc
{
    [super dealloc];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

当然可能由于种种原因(内存泄漏),监听器该销毁的时候并没有被销毁导致的dealloc方法没有被调用(出现这个问题的地方大多是控制器),这样的话,也不会取消注册通知的,这时候有可能第二次创建这个控制器的时候重复注册,所以还有一种比较稳妥的方法是这样

- (void)viewWillAppear:(BOOL)animated
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fuck) name:NotifationTest object:nil];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

在控制器将要出现在屏幕的时候注册通知,控制器将要消失的时候取消注册,一般情况下这样也就够了,但是这个在离开屏幕时是收不到通知的,所以如果有需求是不在当前屏幕也要接收通知的话,这个方式就不可以了..

UIDevice 通知

UIDevice类提供了一个单例对象,它代表着设备,通过它可以获得一些设备相关的信息,比如电池电量值(batteryLevel)、电池状态(batteryState)、设备的类型(model,比如iPod、iPhone等)、设备的系统(systemVersion)

通过[UIDevice currentDevice]可以获取这个单粒对象

UIDevice 对象会不间断地发布一些通知,下列是 UIDevice 对象所发布通知的名称常量:

  1. UIDeviceOrientationDidChangeNotification // 设备旋转
  2. UIDeviceBatteryStateDidChangeNotification // 电池状态
  3. UIDeviceBatteryLevelDidChangeNotification // 电池电量
  4. UIDeviceProximityStateDidChangeNotification // 近距离传感器(比如设备贴近了使用者的脸部)

最后来一发鸡汤

实践是最好的老师,但是智者还能从其他地方有所收货。

© 2024 - 2026 cos @cosine
Powered by theme astro-koharu · Inspired by Shoka