macOS开发:跨类发送NSNotification无法被接收问题求助
问题原因及解决办法
你的代码存在两个核心问题,导致通知始终无法被接收:
1. 监听/发送通知的对象被提前释放
- 在
AppDelegate的applicationDidFinishLaunching方法中,你创建了TestManager实例但未通过强引用持有它:
ARC环境下,这个局部对象会在方法执行完毕后立即被释放,它注册的通知监听也会随之被移除,自然接收不到后续发送的通知。[[TestManager alloc] init]; - 同样,
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
相关产品推荐
相关产品推荐

