不使用继承,如何让所有视图控制器具有接收某个通知并执行某个方法的能力?

不使用继承,更不是一个页面一个页面的添加,你们有什么黑科技完成这个功能?

阅读 2.5k
2 个回答

用分类, 创建一个UIViewController+notification.h分类, 运用runtime交换成自己方法, 在方法中注册通知.

#import "UIViewController+notification.h"
#import <objc/runtime.h>

@implementation UIViewController (notification)
+ (void)load {
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // 获得UIViewController的SEL
        SEL originalSEL = @selector(viewDidLoad);
        // 要替换的SEL
        SEL notiSEL = @selector(noti_viewDidLoad);
        
        // 方法
        Method originalMethod = class_getInstanceMethod([self class], originalSEL);
        Method notiMethod = class_getInstanceMethod([self class], notiSEL);
        
        // 交换两个方法的实现
        method_exchangeImplementations(originalMethod, notiMethod);
    });
}
- (void)noti_viewDidLoad {
    // 这个时候noti_viewDidLoad方法已经被替换了
    [self noti_viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notification:) name:@"notificationName" object:nil];
}
- (void)notification:(NSNotification *)noti {
    // 可在指定的控制器中, 重写此方法
    NSLog(@"%s接收到通知",object_getClassName(self));
}
- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"notificationName" object:nil];
    NSLog(@"%s释放通知",object_getClassName(self));
}
@end

我的理解是使用类别(Category).

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题