如何在Swift视图控制器中访问Objective-C私有变量?
解决AVCaptureVideoDataOutput访问问题的几种方案
别担心,这种在.m文件里封装核心AVCaptureSession但需要对外暴露关联视频输出的场景在iOS开发里很常见,我给你几个实用的方案,完全不用把session暴露到.h文件中:
方案1:通过方法返回视频输出
这是最直接的封装方式,只对外暴露获取视频输出的接口:
- 在你的类的**头文件(.h)**中声明一个获取方法:
@interface YourCameraManager : NSObject // 替换成你的实际类名 - (AVCaptureVideoDataOutput *)videoDataOutput; @end - 在**实现文件(.m)**中实现这个方法,遍历session的输出找到目标实例:
外部调用时,只需要@interface YourCameraManager () @property (nonatomic, strong) AVCaptureSession *session; @end @implementation YourCameraManager // 你的session初始化和配置代码... - (AVCaptureVideoDataOutput *)videoDataOutput { // 遍历session的所有输出,筛选出AVCaptureVideoDataOutput类型的对象 for (AVCaptureOutput *output in self.session.outputs) { if ([output isKindOfClass:[AVCaptureVideoDataOutput class]]) { return (AVCaptureVideoDataOutput *)output; } } return nil; // 未找到时返回nil,你可以根据业务需求做容错处理 } @end[yourCameraManager videoDataOutput]就能拿到视频输出,完全看不到内部的session属性。
方案2:直接封装视频输出为只读属性
如果你的AVCaptureVideoDataOutput是在初始化阶段就创建好的,可以直接把它作为私有属性保存,再对外暴露只读接口:
- 在**实现文件(.m)**的类扩展中声明私有属性:
@interface YourCameraManager () @property (nonatomic, strong) AVCaptureSession *session; @property (nonatomic, strong) AVCaptureVideoDataOutput *videoOutput; @end - 在配置session时,直接初始化并保存
videoOutput:- (void)setupSession { self.session = [[AVCaptureSession alloc] init]; // 配置session的其他代码... // 创建并配置视频输出 self.videoOutput = [[AVCaptureVideoDataOutput alloc] init]; // 设置videoOutput的代理、格式等... [self.session addOutput:self.videoOutput]; } - 在**头文件(.h)**中添加只读属性声明:
外部可以直接通过@interface YourCameraManager : NSObject @property (nonatomic, readonly) AVCaptureVideoDataOutput *videoDataOutput; @endyourCameraManager.videoDataOutput访问,内部依然可以自由修改videoOutput属性,session全程隐藏在.m中。
方案3:用Block回调传递视频输出
如果需要在视频输出准备好后主动通知外部,可以用Block回调的方式:
- 在**头文件(.h)**中声明Block属性:
@interface YourCameraManager : NSObject @property (nonatomic, copy) void(^videoDataOutputReady)(AVCaptureVideoDataOutput *output); @end - 在**实现文件(.m)**中配置好视频输出后触发回调:
外部使用时,只需要设置这个Block就能在视频输出准备好时拿到实例:- (void)setupSession { self.session = [[AVCaptureSession alloc] init]; // 配置session和视频输出... self.videoOutput = [[AVCaptureVideoDataOutput alloc] init]; // 完成配置并添加到session后 if (self.videoDataOutputReady) { self.videoDataOutputReady(self.videoOutput); } }YourCameraManager *manager = [[YourCameraManager alloc] init]; manager.videoDataOutputReady = ^(AVCaptureVideoDataOutput *output) { // 在这里处理视频输出 }; [manager setupSession];
小提示
如果你的session中添加了多个同类型的输出,遍历的时候可以通过AVCaptureConnection的媒体类型(比如AVMediaTypeVideo)或者自定义的标识来精准筛选,避免返回错误的输出。
内容的提问来源于stack exchange,提问作者Barkley
相关产品推荐
相关产品推荐

