NSWindow的sharingType属性生效但取值始终无法正确更新
macOS NSWindow sharingType 回读异常问题解决
问题现象
设置NSWindow的sharingType为NSWindowSharingNone或NSWindowSharingReadOnly后,从第二次循环开始调用sharingType获取值时,始终返回0(即NSWindowSharingNone),但窗口防截图的功能本身正常,仅属性回读出现异常。
原因分析
这是AppKit框架的已知行为:当窗口共享类型设置为NSWindowSharingNone或NSWindowSharingReadOnly时,系统内部不会维护该属性的回读值,导致后续调用sharingType无法返回实际设置的状态。框架优先保证功能生效,而非属性值的回读准确性。
解决方案
放弃依赖系统属性的回读,自行维护窗口的共享状态即可。以下是修改后的代码:
@interface ViewController () { NSWindowSharingType _currentSharingType; // 自行维护当前共享状态 } @property (strong) NSWindow* childWindow; @property (strong) NSTimer* timer; @end - (void)viewDidLoad { [super viewDidLoad]; [self createWindowAction: nil]; _currentSharingType = NSWindowSharingNone; // 初始化状态 [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(triggerAction:) name: @"NotificationMessageEvent" object: nil]; self.timer = [NSTimer scheduledTimerWithTimeInterval: 4.0f repeats: YES block:^(NSTimer * _Nonnull timer) { // 切换状态 _currentSharingType = (_currentSharingType == NSWindowSharingNone) ? NSWindowSharingReadOnly : NSWindowSharingNone; NSLog( @"Current maintained sharing type: %lu", (unsigned long)_currentSharingType ); NSLog( @"Updating sharing type to: %lu", (unsigned long)_currentSharingType ); [self.childWindow setSharingType: _currentSharingType]; // 直接使用自行维护的状态,不再依赖系统回读 NSLog( @"After update, maintained sharing type: %lu", (unsigned long)_currentSharingType ); NSLog(@""); }]; } -(void) dealloc { [self.timer invalidate]; self.timer = nil; } - (IBAction)createWindowAction:(NSButton *)sender { NSLog(@"createWindowAction"); if (!self.childWindow) { self.childWindow = [[NSWindow alloc] initWithContentRect: CGRectMake( 100.0f, 150.0f, 500.0f, 400.0f ) styleMask: NSWindowStyleMaskBorderless | NSWindowStyleMaskNonactivatingPanel backing: NSBackingStoreBuffered defer: NO]; self.childWindow.collectionBehavior = NSWindowCollectionBehaviorMoveToActiveSpace | NSWindowCollectionBehaviorTransient | NSWindowCollectionBehaviorAuxiliary | NSWindowCollectionBehaviorParticipatesInCycle; self.childWindow.hasShadow = NO; self.childWindow.accessibilityElement = YES; [self.childWindow setCanHide: NO]; // 初始化窗口时同步设置共享类型 [self.childWindow setSharingType: _currentSharingType]; } [self.childWindow orderFrontRegardless]; }
关键修改点
- 用
NSWindowSharingType类型的变量_currentSharingType替代原布尔值,直接维护当前状态 - 所有状态判断、日志输出均基于自行维护的变量,不再调用
[self.childWindow sharingType] - 窗口初始化时同步设置共享类型,确保初始状态一致
验证说明
若需确认功能是否生效,直接用系统截图工具测试窗口是否被截取即可,无需依赖属性回读值。
内容的提问来源于stack exchange,提问作者Oleg
相关产品推荐
相关产品推荐

