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

macOS开发:跨类发送NSNotification无法被接收问题求助

问题原因及解决办法

你的代码存在两个核心问题,导致通知始终无法被接收:

1. 监听/发送通知的对象被提前释放

  • 在AppDelegate的applicationDidFinishLaunching方法中,你创建了TestManager实例但未通过强引用持有它:
    [[TestManager alloc] init];
    
    ARC环境下,这个局部对象会在方法执行完毕后立即被释放,它注册的通知监听也会随之被移除,自然接收不到后续发送的通知。
  • 同样,TestManager的init方法中创建的TestObserver也是局部对象,没有强引用持有,会被立即释放,导致定时器的目标对象失效,后续无法正常触发通知发送逻辑。

2. 通知回调方法签名不规范(可选优化)

虽然不带参数的notificationReceived方法理论上能被调用,但苹果官方推荐的通知回调方法应当接收NSNotification参数,这样更符合API设计规范,避免潜在的调用异常。


修改后的代码

AppDelegate 类

#import <Cocoa/Cocoa.h>
#import "TestManager.h"

@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (strong, nonatomic) TestManager *testManager; // 添加强引用属性
@end

------------------------------

#import "AppDelegate.h"

@interface AppDelegate ()
@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    NSLog(@"did finish launching");
    self.testManager = [[TestManager alloc] init]; // 用属性持有对象
}
@end

TestManager 类

#import <AppKit/AppKit.h>
#import "TestObserver.h"

@interface TestManager : NSObject
@property (strong, nonatomic) TestObserver *testObserver; // 添加强引用属性
@end

------------------------------

#import "TestManager.h"

@implementation TestManager
- (instancetype)init {
    self = [super init];

    if (self) {
        NSLog(@"manager init");
        self.testObserver = [[TestObserver alloc] init]; // 用属性持有对象
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationReceived:) name:@"testnotification" object:nil]; // 修改selector带参数
    }

    return self;
}

// 修改方法签名,添加NSNotification参数
- (void)notificationReceived:(NSNotification *)notification {
    NSLog(@"notification received");
}

// 对象释放时移除通知监听(推荐)
- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end

TestObserver 类

#import <AppKit/AppKit.h>

@interface TestObserver : NSObject
@end

------------------------------

#import "TestObserver.h"

@implementation TestObserver
- (instancetype)init {
    self = [super init];

    if (self) {
        NSLog(@"observer init");
        [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(sendNotification) userInfo:nil repeats:YES];
    }

    return self;
}

- (void)sendNotification {
    NSLog(@"observer post");
    [[NSNotificationCenter defaultCenter] postNotificationName:@"testnotification" object:nil];
}
@end

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 23:01:11