IBOutlet始终为nil及AVPlayerWindow无法成为关键窗口问题求助
问题排查与解决思路
问题现象
- 窗口控制器加载XIB后,AVPlayerView的IBOutlet
playerView始终为nil,无法赋值AVPlayer - 即使无其他窗口,AVPlayer窗口无法成为关键窗口
- XIB连线已确认正确,运行无异常抛出
一、解决playerView为nil的核心方案
确认XIB的File's Owner绑定
打开MoviePlayer.xib,检查File's Owner的Class是否设置为MoviePlayerWindowController——IBOutlet必须连接到对应控制器的属性,否则加载时无法完成绑定。利用窗口控制器生命周期回调
XIB中控件的加载完成是在windowDidLoad方法之后,不要在控制器初始化后立即访问playerView。将AVPlayer赋值逻辑移到MoviePlayerWindowController的windowDidLoad中:// MoviePlayerWindowController.m - (void)windowDidLoad { [super windowDidLoad]; // 确保thePlayer已传递到当前控制器 if (self.thePlayer) { self.playerView.player = self.thePlayer; } }检查属性声明类型
确保playerView是强引用声明,弱引用可能导致控件被提前释放:@property (nonatomic, strong) IBOutlet AVPlayerView *playerView;
二、修复窗口无法成为关键窗口的问题
调整窗口显示调用顺序
当前代码同时调用makeKeyAndOrderFront:和showWindow:存在逻辑冲突,二选一即可,推荐保留makeKeyAndOrderFront:并调整顺序:// AppController.m中修改showMoviePlayerWindow方法 if (![self myMoviePlayerWindowController]) { myMoviePlayerWindowController = [[MoviePlayerWindowController alloc] initWithWindowNibName:@"MoviePlayer"]; [self set_myMoviePlayerWindowController:myMoviePlayerWindowController]; } NSWindow *playerWindow = [[self myMoviePlayerWindowController] window]; [playerWindow center]; [playerWindow makeKeyAndOrderFront:self];检查窗口属性设置
打开XIB中的窗口,确认以下属性已勾选:Can Become Key WindowCan Become Main Window
同时取消Visible At Launch(因为是通过代码手动触发显示)。
三、代码逻辑优化建议
- 移除依赖固定延迟的
performSelector:withObject:afterDelay:,改用窗口通知回调触发播放:// MoviePlayerWindowController.m的windowDidLoad中添加监听 - (void)windowDidLoad { [super windowDidLoad]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(startPlayback) name:NSWindowDidBecomeMainNotification object:self.window]; } - (void)startPlayback { [self.playerView.player play]; } // 销毁时移除监听 - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } - 将AVPlayer的创建逻辑移到
MoviePlayerWindowController内部,避免跨控制器传递时的生命周期不匹配问题。
内容的提问来源于stack exchange,提问作者ScottHa
相关产品推荐
相关产品推荐

