美文网首页iOS开发
iOS通知使用总结

iOS通知使用总结

作者: SayCain | 来源:发表于2020-06-25 21:10 被阅读0次

    NSNotification

    一、添加通知

    1.使用selector添加

    - (void)addObserver:(id)observer 
               selector:(SEL)aSelector 
                   name:(nullable NSNotificationName)aName 
                 object:(nullable id)anObject;
    

    2.使用block添加

    - (id <NSObject>)addObserverForName:(nullable NSNotificationName)name 
                                 object:(nullable id)obj queue:(nullable NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *note))block;
    

    使用block添加了多个相同的通知,接受通知时会并发的调用。

    二、发送通知

    1.使用NSNotificationCenter中方法

    - (void)postNotification:(NSNotification *)notification;
    - (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject;
    - (void)postNotificationName:(NSNotificationName)aName 
                          object:(nullable id)anObject 
                        userInfo:(nullable NSDictionary *)aUserInfo;
    

    2.使用NSNotificationQueue

    - (void)enqueueNotification:(NSNotification *)notification postingStyle:(NSPostingStyle)postingStyle;
    - (void)enqueueNotification:(NSNotification *)notification 
                   postingStyle:(NSPostingStyle)postingStyle 
                   coalesceMask:(NSNotificationCoalescing)coalesceMask 
                       forModes:(nullable NSArray<NSRunLoopMode> *)modes;
    

    使用该方法发送的异步通知,可以使用下列方法取消:

    - (void)dequeueNotificationsMatching:(NSNotification *)notification coalesceMask:(NSUInteger)coalesceMask;
    

    三、实现原理

    typedef struct NCTbl {        // 通知存储的数据结构
        Observation   *wildcard;  // 保存没传名字没传对象的通知,是个链表
        MapTable       nameless;  // 保存未传入名字的通知
        MapTable       named;     // 保存传入名字的通知,传入名字未传入对象的会创建一个相同的key
    } NCTable;
    
    typedef struct Obs {
        id        observer;       
        SEL       selector;       
        struct Obs    *next;      
        struct NCTbl  *link;   
    } Observation;
    

    四、发送通知到指定线程

    1. 判断接受通知不在指定线程,发送一个信号让指定线程处理。参考
    2. 通过子类化NSNotificationCenter或者单独写个类完成转发。

    五、总结

    1. SEL方式添加的通知,接收通知和发送通知在同一线程。
    2. 对象销毁时记得移除观察者,通过SEL添加的iOS9以后可以不用移除;而通过block形式添加需要手动移除。
    3. 通过添加nil的通知,可以捕获到系统事件通知,包括线程销毁、亮度改变、锁屏、剪切板变动等。
    4. CFNotificationCenterGetDarwinNotifyCenter()可以跨进程进行通知,但是不能传递对象。

    参考

    -[1] 官方文档

    -[2] Stackoverflow

    相关文章

      网友评论

        本文标题:iOS通知使用总结

        本文链接:https://www.haomeiwen.com/subject/dakefktx.html