項(xiàng)目中經(jīng)常會(huì)用到通知傳值,如何將通知簡(jiǎn)化合并到極致,且看下文
1龄捡、創(chuàng)建工具類用于發(fā)送通知
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface SJObjectTool : NSObject
+ (void)SJPostNotificationClass:(Class)className event:(NSInteger)event param:(nullable NSDictionary *)param;
@end
NS_ASSUME_NONNULL_END
#import "SJObjectTool.h"
@implementation SJObjectTool
//className:類名,用于區(qū)分通知的對(duì)象
//event:事件類型慷暂,用于區(qū)分對(duì)象收到的事件類型
//param:傳的值
+ (void)SJPostNotificationClass:(Class)className event:(NSInteger)event param:(nullable NSDictionary *)param
{
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setValue:@(1) forKey:@"_notify_event_type"];
[dict setValue:@(event) forKey:@"_notify_event_event"];
[dict setObject:param forKey:@"_notify_event_param"];
//SJClassNameNotifi:宏定義聘殖,根據(jù)類名加上前綴來定義一個(gè)新的通知name
[[NSNotificationCenter defaultCenter] postNotificationName:SJClassNameNotifi(className) object:nil userInfo:dict];
}
@end
2、宏定義如下(寫在自定義的宏定義類中呜呐,頭文件可寫在pch文件中方便使用)
#define SJClassNameNotifi(cls) [@"_notify_event_class_" stringByAppendingString:NSStringFromClass(cls)]
//使用此宏定義來發(fā)送通知
#define SJ_NOTIFICATION_OBJ(cls,e,dic) [SJObjectTool SJPostNotificationClass:cls event:e param:dic]
3就斤、收通知操作封裝(由于我們所有的類最終都繼承自NSObject,所以創(chuàng)建NSObject的分類SJNotifiEvent)
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <objc/message.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSObject (SJNotifiEvent)
- (void)SJAddNotifiCationEvent;
- (void)SJRemoveNotificationEvent;
- (void)SJNotificationEvent:(NSInteger)event param:(NSDictionary *)param;
@end
NS_ASSUME_NONNULL_END
#import "NSObject+SJNotifiEvent.h"
@implementation NSObject (SJNotifiEvent)
- (void)SJAddNotifiCationEvent{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(__SJ_notifyEvent:) name:SJClassNameNotifi(self.class) object:nil];
}
- (void)SJRemoveNotificationEvent{
[[NSNotificationCenter defaultCenter] removeObserver:self name:SJClassNameNotifi(self.class) object:nil];
}
- (void)__SJ_notifyEvent:(NSNotification *)notify
{
NSDictionary *dict = notify.userInfo;
if([dict isKindOfClass:[NSDictionary class]] && [[dict objectForKey:@"_notify_event_type"] intValue] == 1){
if([self respondsToSelector:@selector(SJNotificationEvent:param:)]){
NSInteger event = [[dict objectForKey:@"_notify_event_event"] integerValue];
NSDictionary *param = dict[@"_notify_event_param"];
void (*SJ_msgsend)(id, SEL, NSInteger , NSDictionary *) = (void (*)(id, SEL, NSInteger , NSDictionary *))objc_msgSend;
SJ_msgsend(self, @selector(SJNotificationEvent:param:), event, param);
}
}
}
4蘑辑、在頁面中使用
比如有兩個(gè)頁面 AViewController洋机、BViewcontroller。AViewController發(fā)通知洋魂,BViewcontroller接收
//AViewController類的發(fā)送通知處 這里宏定義的參數(shù)在上面解釋過绷旗,中間的SJActionEventSendMessage是event我們隨后會(huì)做枚舉處理,見下文
SJ_NOTIFICATION_OBJ(BViewcontroller.class, SJActionEventSendMessage, @{@"param1":@(1314),@"param2":@"520"});
//BViewcontroller類中
//1副砍、首先在viewDidLoad中添加方法
- (void)viewDidLoad {
[super viewDidLoad];
// 添加接收通知(NSObject分類中的方法)
[self EMOAddNotifiCationEvent];
}
/// action 事件
/// @param event action 類型
/// @param param action 參數(shù)
- (void)EMONotificationEvent:(NSInteger)event param:(NSDictionary *)param{
// NSLog(@"收取通知回調(diào)___%ld",event);
if (event == SJActionEventSendMessage){
//事件處理
NSNumber *param1 = param[@"param1"];
NSString *param2 = param[@"param2"];
}
}
//不要忘記在dealloc中移除通知
- (void)dealloc{
[self SJRemoveNotificationEvent];
}
5衔肢、為了方便事件類型的管理,我們把event作為枚舉處理
我們可以自定義一個(gè)專門放枚舉的SJEnums_h類豁翎,只需要.h文件即可角骤,所以建 Header File 文件,創(chuàng)建枚舉心剥。頭文件放到pch中
#ifndef SJEnums_h
#define SJEnums_h
// action 點(diǎn)擊類型
typedef NS_ENUM(NSInteger, SJActionEventType) {
SJActionEventSendMessage = 0, // 發(fā)送消息通知
SJActionEventReceiveMessage, // 接收消息通知
}
#endif
通過上述操作邦尊,有以下好處:
1、通知通過宏定義在操作优烧,簡(jiǎn)便快捷
2蝉揍、不用糾結(jié)通知的名字,直接誰接收通知就用誰的類名
3畦娄、通過類名區(qū)分接收對(duì)象又沾,通過event區(qū)分事件,清晰明了
4熙卡、event通過枚舉來管理杖刷,方便擴(kuò)展和維護(hù)