菜单

Objective-C 实现

相关源文件

本文档涵盖了 Protocol Buffers (protobuf) 的 Objective-C 实现。它描述了 Objective-C 运行时库和代码生成器的架构、组件和使用模式。有关 Protocol Buffer 的一般概念,请参阅 概览

概述

Objective-C 实现提供了对 Apple 平台应用程序(iOS、macOS、tvOS、watchOS 和 visionOS)中使用 Protocol Buffers 的原生支持。它包括:

  1. 运行时库(Objective-C Protobuf 框架)
  2. 用于 protoc(Protocol Buffer 编译器)的代码生成器插件
  3. 对 Protocol Buffers 的知名类型(well-known types)的支持
  4. CocoaPods 集成,方便项目设置

该实现遵循 Objective-C 约定,同时保持与 Protocol Buffer 语义的兼容性,提供高效的消息序列化和反序列化。

来源:Protobuf.podspec1-54

架构

类命名和结构

Objective-C 实现使用“GPB”(Google Protocol Buffers)作为其类的前缀。每个 Protocol Buffer 消息类型都表示为一个具有此前缀的 Objective-C 类,并继承自一个公共基类。

主要组成部分包括:

  • 消息类(例如,GPBAnyGPBTimestamp
  • 内部字段值的存储结构
  • 用于提供运行时类型信息的描述符(Descriptors)
  • 用于序列化和字段访问的辅助方法

来源:objectivec/GPBAny.pbobjc.m52-108 objectivec/GPBTimestamp.pbobjc.m52-103 objectivec/GPBDuration.pbobjc.m52-103

存储模型

每个生成的消息类使用一个私有的 C 结构来存储其字段值。这种方法提供了高效的内存使用和性能。该结构通常包含:

  1. 一个位数组,用于跟踪设置了哪些字段(_has_storage_
  2. 原始类型、字符串和嵌套消息的字段值
  3. 用于重复字段和映射的集合对象

例如,检查 GPBAny 的存储结构

来源:objectivec/GPBAny.pbobjc.m57-61

描述符系统

描述符系统是 Objective-C 实现的骨干,它提供了关于消息、字段、枚举和其他 Protocol Buffer 构造的运行时类型信息。

每个生成的消息类都实现了一个 +descriptor 类方法,该方法返回有关消息类型的元数据。此描述符包含:

  • 字段描述(名称、编号、类型、存储中的偏移量)
  • 消息名称和包信息
  • Oneof 定义
  • 嵌套类型信息

来源:objectivec/GPBAny.pbobjc.m65-108 objectivec/GPBTimestamp.pbobjc.m65-103 objectivec/GPBDuration.pbobjc.m65-103

知名类型

Objective-C 实现对 Protocol Buffers 的知名类型(well-known types)提供了专门支持。这些是 Protocol Buffers 发行版中定义的常用消息类型。

这些类型包括:

  • GPBAny (google.protobuf.Any)
  • GPBTimestamp (google.protobuf.Timestamp)
  • GPBDuration (google.protobuf.Duration)
  • GPBEmpty (google.protobuf.Empty)
  • GPBFieldMask (google.protobuf.FieldMask)
  • GPBStructGPBValueGPBListValue (google.protobuf.Struct)
  • 包装器类型,如 GPBBoolValueGPBStringValue (google.protobuf.wrappers)

每个知名类型在运行时库中都有专门的处理,以提供更自然的 Objective-C API,同时保持 Protocol Buffer 语义。

来源:objectivec/GPBAny.pbobjc.m1-118 objectivec/GPBDuration.pbobjc.m1-113 objectivec/GPBEmpty.pbobjc.m1-81 objectivec/GPBFieldMask.pbobjc.m1-94 objectivec/GPBSourceContext.pbobjc.m1-94 objectivec/GPBStruct.pbobjc.m1-304 objectivec/GPBTimestamp.pbobjc.m1-113 objectivec/GPBType.pbobjc.m1-749 objectivec/GPBWrappers.pbobjc.m1-469

代码生成

Protocol Buffer 编译器(protoc)使用 Objective-C 插件为每个 .proto 文件生成 Objective-C 代码。对于 .proto 文件中定义的每种消息类型,生成器会生成:

  1. 一个 .pbobjc.h 头文件,包含类声明、属性定义和枚举声明
  2. 一个 .pbobjc.m 实现文件,包含消息描述符、存储结构和其他实现细节

生成的代码特性

生成的代码包括:

  1. 消息类:具有每个字段的动态属性的 Objective-C 类
  2. 枚举定义:带有验证方法的 Objective-C 枚举
  3. 存储结构:用于高效字段存储的 C 结构
  4. 描述符方法:用于运行时类型信息的 +descriptor 方法
  5. 字段访问:用于字段访问的属性和辅助方法
  6. 序列化支持:与运行时库集成,用于序列化/反序列化

属性生成

Protocol Buffer 消息中的字段作为 Objective-C 属性在生成的代码中公开。

Proto 字段类型Objective-C 属性类型
int32, int64 等int32_t, int64_t 等
float, doublefloat, double
boolBOOL
字符串NSString*
bytesNSData*
枚举enum 类型 (int32_t)
message生成的消息类*
repeated TNSMutableArray*
map<K,V>NSMutableDictionary<K,V>*

这些属性使用 @dynamic 关键字声明,并且访问器由运行时库根据描述符信息提供。

来源:objectivec/GPBAny.pbobjc.m54-55 objectivec/GPBTimestamp.pbobjc.m54-55 objectivec/GPBStruct.pbobjc.m86

集成

CocoaPods 集成

Objective-C 实现可以通过 CocoaPods 轻松集成到 iOS 和 macOS 项目中。pod 规范包括:

pod 'Protobuf'

支持的平台

  • iOS 15.0+
  • macOS 11.0+
  • tvOS 12.0+
  • watchOS 6.0+
  • visionOS 1.0+

来源:Protobuf.podspec1-54

版本控制

该实现包含版本兼容性检查,以确保生成的代码与运行时库版本兼容。

#if GOOGLE_PROTOBUF_OBJC_VERSION < 40311
#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources.
#endif

Objective-C 实现的当前版本为 4.31.0。

来源:Protobuf.podspec7-8 objectivec/GPBAny.pbobjc.m10-15

生成的代码详细信息

消息实现

生成的消息类遵循一致的模式:

  1. 消息类声明,带有该文件的根类
  2. 带有 @dynamic 的字段属性声明
  3. 存储结构定义
  4. 描述符实现
  5. 枚举和 oneof 的辅助方法

.proto 文件中定义的字段,并附加了对设置了哪些字段的跟踪。

来源: objectivec/GPBAny.pbobjc.m30-110 objectivec/GPBStruct.pbobjc.m83-296

枚举实现

Protocol Buffer 枚举实现为 C 枚举,并带有用于验证和转换的辅助函数

  1. 枚举值定义
  2. 描述符函数(例如:GPBSyntax_EnumDescriptor
  3. 验证函数(例如:GPBSyntax_IsValidValue

生成的代码包括原子引用处理,以确保线程安全和高效的描述符缓存。

来源: objectivec/GPBType.pbobjc.m52-88 objectivec/GPBStruct.pbobjc.m49-80

内存管理

Objective-C 实现使用了标准的 Objective-C 内存管理模式

  1. 消息对象由 ARC(自动引用计数)管理
  2. 内部字段根据类型使用适当的内存管理(对象使用 retain,字符串使用 copy)
  3. 存储结构高效处理内存布局和字段访问
  4. 消息对象在解除分配时会执行正确的清理

该实现非常注意避免内存泄漏,同时提供自然的 Objective-C API。

来源: objectivec/GPBAny.pbobjc.m57-61 objectivec/GPBTimestamp.pbobjc.m57-61 objectivec/GPBType.pbobjc.m220-229

使用模式

生成的 Objective-C 代码遵循常见的 Objective-C 对象创建和属性访问模式

该实现提供了熟悉的 Objective-C API,同时保持了 Protocol Buffers 的效率和语义。