# iOS SDK · Objective-C 封装 C++ 核心

> iOS/macOS 上的 WebRTC 是一层 Objective-C 封装：RTCPeerConnection 等 RTC 前缀类包着 C++ 的 api/ 对象。这一章读 objc/，讲清 ObjC++ 为什么让这层绑定比 Android 的 JNI 更顺滑，以及 ARC 和 C++ 引用计数怎么在边界上握手。

- 作者：David（道雾轩）
- 专栏：音视频与 WebRTC 详解（https://daiw.org/manual/webrtc.md）
- 最后更新：2026-07-15
- 原文：https://daiw.org/manual/webrtc/ios-sdk
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

# iOS SDK · Objective-C 封装 C++ 核心

[Android 用 JNI](https://daiw.org/manual/webrtc/android-sdk)，Apple 平台（iOS/macOS）用 **Objective-C 封装**。同样是[给 C++ 核心套一层语言绑定](https://daiw.org/manual/webrtc/platform-overview)，但 ObjC 这层比 JNI **顺滑得多**——原因很有意思。这一章看 `objc/`。

## RTC 前缀的 Objective-C 类

iOS 开发者用的是一组 `RTC` 前缀的 Objective-C 类：`RTCPeerConnectionFactory`、`RTCPeerConnection`、`RTCVideoTrack`……它们和 [Android 的 Java 壳](https://daiw.org/manual/webrtc/android-sdk)一样，是[对 `api/` C++ 接口的封装](https://daiw.org/manual/webrtc/factory-and-context)：

<Callout type="info">
  **`RTCPeerConnection` 等 ObjC 类**持有并封装** C++ 侧的 [`PeerConnectionInterface`](https://daiw.org/manual/webrtc/peer-connection-object)，把 Objective-C 方法调用转成对 C++ 对象的调用——和 [Android JNI 桥](https://daiw.org/manual/webrtc/android-sdk)是同一个“[壳 + 核心](https://daiw.org/manual/webrtc/platform-overview)”模式，只是换了语言。** iOS 应用 `[peerConnection offerForConstraints:...]` → ObjC 封装 → C++ [`CreateOffer`](https://daiw.org/manual/webrtc/offer-answer-handler)；C++ 的[事件](https://daiw.org/manual/webrtc/proxy-pattern) → 回调 ObjC 的 `RTCPeerConnectionDelegate`。**逻辑仍全在[共享的 C++ 核心](https://daiw.org/manual/webrtc/call-recap)**，ObjC 层只做转发。到这里，你已看到[三种绑定](https://daiw.org/manual/webrtc/platform-overview)（JS/Blink、[Java/JNI](https://daiw.org/manual/webrtc/android-sdk)、ObjC）对着[同一个 `api/`](https://daiw.org/manual/webrtc/factory-and-context)——这就是[一核多绑定的威力](https://daiw.org/manual/webrtc/platform-overview)。
</Callout>

## ObjC++ 让绑定几乎“免费”

关键区别来了——为什么 ObjC 绑定比 JNI 简单？

<Callout type="info">
  **因为 **Objective-C++（`.mm` 文件）可以直接混写 Objective-C 和 C++**——一个 `.mm` 文件里，ObjC 方法体内能直接 `new` C++ 对象、直接调 C++ 方法，**不需要 [JNI 那样的编组层](https://daiw.org/manual/webrtc/android-sdk)**。** [Android 之所以要 `java_types`、`scoped_java_ref` 一整套工具](https://daiw.org/manual/webrtc/android-sdk)，是因为 [Java 和 C++ 是两个完全隔离的世界](https://daiw.org/manual/webrtc/android-sdk)，跨界要显式编组、要管 JNI 引用、要附着线程。而 **ObjC 和 C++ 本就同源**（都从 C 来、共享内存模型），ObjC++ 编译器直接让两者在同一文件里互操作：

  - ObjC 类的成员**直接**是 `scoped_refptr<PeerConnectionInterface>`，不用藏在 `long` 指针里。
  - 调 C++ 方法就是普通函数调用，**没有 JNI 那层转换开销和样板**。
  - 不用 [`AttachCurrentThread` 之类的线程附着](https://daiw.org/manual/webrtc/android-sdk)——没有 JVM。

  所以 iOS 绑定层**薄得多、也快得多**。这解释了一个现象：同样封装同一个核心，[Android 的 SDK 代码](https://daiw.org/manual/webrtc/android-sdk)明显比 iOS 的复杂——不是 WebRTC 偏心，是 JNI 边界本身就比 ObjC++ 边界麻烦。
</Callout>

## ARC 与 C++ 引用计数握手

一个仍需小心的接缝：内存管理。ObjC 用 **ARC**（Automatic Reference Counting，自动引用计数），C++ 核心用 [`scoped_refptr`](https://daiw.org/manual/webrtc/scoped-refptr)——**两套引用计数系统在边界相遇**。ObjC 对象的生死由 ARC 管，它内部持有的 [C++ `scoped_refptr`](https://daiw.org/manual/webrtc/scoped-refptr) 会在 ObjC 对象析构（`dealloc`）时释放，从而两套计数[各自正确、又在边界衔接](https://daiw.org/manual/webrtc/scoped-refptr)。有趣的是[两边都是“引用计数”哲学](https://daiw.org/manual/webrtc/scoped-refptr)（[ObjC ARC 和 WebRTC 的 `scoped_refptr` 撞了同一个思想](https://daiw.org/manual/webrtc/scoped-refptr)），衔接因此相对自然——ObjC 对象活着，它引用的 C++ 核心对象就活着。

```mermaid
flowchart LR
    subgraph ObjC["Objective-C 层(objc/,ARC 管)"]
        RPC["RTCPeerConnection<br/>成员: scoped_refptr<...>"]
        DEL["RTCPeerConnectionDelegate"]
    end
    subgraph Native["C++ 核心(api/,scoped_refptr 管)"]
        CPC["PeerConnectionInterface"]
    end
    RPC -->|"ObjC++ 直接调用"| CPC
    CPC -->|"事件回调"| DEL
```

此外，iOS/macOS 平台层还接入 **Apple 特有的能力**：用 [VideoToolbox 做硬件编解码](https://daiw.org/manual/webrtc/video-encoder-abstraction)、用 AVFoundation [采集摄像头 / 麦克风](https://daiw.org/manual/webrtc/video-capture)——这些是[平台采集 / 渲染层](https://daiw.org/manual/webrtc/platform-overview)的 Apple 实现，接到[共享核心的编解码器抽象](https://daiw.org/manual/webrtc/video-encoder-abstraction)和[音频设备接口](https://daiw.org/manual/webrtc/audio-device-mixer)上。

## 小结与下一章

iOS/macOS 的 WebRTC 是一层 **Objective-C 封装**：`RTCPeerConnection` 等 `RTC` 前缀类包着 C++ 的 [`api/` 对象](https://daiw.org/manual/webrtc/peer-connection-object)，和 [Android JNI](https://daiw.org/manual/webrtc/android-sdk) 同为“[壳 + 核心](https://daiw.org/manual/webrtc/platform-overview)”。但 **ObjC++（`.mm`）能直接混写 ObjC 与 C++**，[不需要 JNI 那套编组 / 引用 / 线程附着](https://daiw.org/manual/webrtc/android-sdk)，所以绑定层[薄得多、快得多](https://daiw.org/manual/webrtc/ios-sdk)。边界上 **ARC 与 [`scoped_refptr`](https://daiw.org/manual/webrtc/scoped-refptr) 两套引用计数握手**（ObjC 对象析构时释放持有的 C++ 引用），因[同为引用计数哲学](https://daiw.org/manual/webrtc/scoped-refptr)而自然衔接。平台层还接入 [VideoToolbox](https://daiw.org/manual/webrtc/video-encoder-abstraction)/AVFoundation 等 Apple 能力。

绑定层讲完了，接下来看**平台相关的采集**——先是桌面的屏幕 / 窗口捕获。👉 [桌面采集](https://daiw.org/manual/webrtc/desktop-capture)。

## 参考资料

- [1] libwebrtc 源码.`sdk/objc/`（`RTCPeerConnection`、`RTCPeerConnectionFactory` 等）、`sdk/objc/native/`。
- [2] 关联[Android JNI](https://daiw.org/manual/webrtc/android-sdk)、[引用计数](https://daiw.org/manual/webrtc/scoped-refptr)、[编解码器抽象](https://daiw.org/manual/webrtc/video-encoder-abstraction)。
- [3] Apple VideoToolbox / AVFoundation 文档。
