You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Notification Observer在A、B类间实现推送导航?

针对你的通知实现方案的优化建议

嘿,我来分享几个实际开发中能让这个通知实现更健壮、更易维护的建议:

  • 务必移除通知观察者,防止崩溃
    目前你的代码只添加了观察者,但没有在A类销毁时移除。如果A类的ViewController已经被释放(比如被pop出导航栈),这时候B类发送通知,系统会尝试给已释放的对象发送消息,直接导致崩溃。建议在dealloc方法里移除观察者:

    - (void)dealloc {
        // 移除当前对象的所有观察者,也可以精准移除指定通知
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    

    要是你想更精准,也可以只移除这个特定的通知:

    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"notificationName" object:nil];
    
  • 用常量替代硬编码的通知名称
    直接写@"notificationName"属于硬编码,不仅容易打错,后续重构或者修改通知名称时要找遍所有用到的地方,非常麻烦。建议定义全局常量:

    // 在公共头文件或者.pch文件中声明
    extern NSString *const kNotificationSomethingHappens;
    
    // 在A类或者专门的常量文件中实现
    NSString *const kNotificationSomethingHappens = @"notificationName";
    

    之后注册和发送通知都用这个常量,代码可读性和可维护性都会提升不少。

  • 预留数据传递的扩展空间
    当前的通知没有传递任何数据,如果以后需要从B类给A类传参数(比如跳转页面需要的配置信息),可以利用通知的userInfo字典:
    // B类发送通知时携带数据

    NSDictionary *userInfo = @{@"targetVCParam": @"someValue"};
    [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationSomethingHappens object:self userInfo:userInfo];
    

    // A类接收时取出数据

    -(void)somethingHappens:(NSNotification*)notification {
        NSString *param = notification.userInfo[@"targetVCParam"];
        // 用参数做相应处理
        // ... 原有跳转代码
    }
    

    这样后续扩展功能不用修改通知的基础结构,更灵活。

  • 缩小通知接收范围(可选)
    你注册观察者时用了object:nil,这意味着A类会接收所有发送notificationName的通知。如果B类是这个通知的唯一发送者,建议在注册时指定B类的实例,这样只接收来自B类的通知,避免其他地方误发相同名称的通知导致A类意外触发:

    // 假设你能在A类中拿到B类的实例bInstance
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(somethingHappens:) name:kNotificationSomethingHappens object:bInstance];
    
  • 完善页面跳转的代码
    目前你在somethingHappens:里创建了导航控制器和目标VC,但没有把这个导航控制器显示出来!记得加上present或者push的逻辑,比如:

    -(void)somethingHappens:(NSNotification*)notification {
        NavigationController *navigationController = [self.storyboard instantiateViewControllerWithIdentifier:@"contentViewController"];
        UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"loyaltyVC"];
        navigationController.viewControllers = @[vc];
        // 显示导航控制器,这里根据你的需求选present或者push
        [self presentViewController:navigationController animated:YES completion:nil];
    }
    

    另外,建议加上实例化失败的判断,避免storyboard ID写错导致崩溃:

    NavigationController *navigationController = [self.storyboard instantiateViewControllerWithIdentifier:@"contentViewController"];
    if (!navigationController) {
        NSLog(@"Failed to load NavigationController with ID: contentViewController");
        return;
    }
    

内容的提问来源于stack exchange,提问作者serkanmalagic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 20:52:28