在Swift中强制初始化带有不可用构造器的SCWindow类
Swift中绕过SCWindow构造器限制的方法
问题背景
SCWindow类的所有构造器均被标记为不可用,在Objective-C中可以通过类扩展添加自定义构造器绕过该限制,代码如下:
#import <ScreenCaptureKit/ScreenCaptureKit.h> @interface SCWindow (InitWithId) @property CGWindowID windowID; - (instancetype _Nonnull)initWithId:(CGWindowID)windowID; @end @implementation SCWindow (InitWithId) @dynamic windowID; - (instancetype _Nonnull)initWithId:(CGWindowID)windowID { self = [super init]; if (self) { [self setValue:[NSNumber numberWithInteger:windowID] forKey:@"windowID"]; } return self; } @end
由于Swift扩展仅允许添加便利构造器,无法直接添加指定构造器,因此需要用其他方式实现类似功能。
可行解决方案
方案1:复用Objective-C分类(最直接)
将上述Objective-C分类代码保存为.m和.h文件,在Swift项目中通过桥接文件导入该分类的头文件,即可直接在Swift中调用自定义构造器:
let window = SCWindow(id: targetWindowID)
这种方法完全复用已验证的OC逻辑,无需额外修改。
方案2:Swift扩展中添加静态创建方法
由于Swift无法在扩展中添加指定构造器,可通过静态方法结合KVC实现实例创建:
import ScreenCaptureKit extension SCWindow { static func create(with windowID: CGWindowID) -> SCWindow { // 基于NSObject初始化实例(SCWindow继承自NSObject) guard let instance = NSObject() as? SCWindow else { fatalError("Failed to initialize SCWindow instance") } // 通过KVC设置windowID属性 instance.setValue(windowID, forKey: "windowID") return instance } }
调用方式:
let targetWindow = SCWindow.create(with: yourWindowID)
注意事项
- 两种方法均依赖私有API行为(直接访问未公开的
windowID属性、绕过官方构造器限制),苹果可能在后续系统版本中修改相关实现,导致代码失效。 - 使用KVC时需确保
windowID属性的键名未发生变化,否则会抛出NSUnknownKeyException异常。
内容的提问来源于stack exchange,提问作者Jason1923
相关产品推荐
相关产品推荐

