通过消息转发机制让OC模拟多继承是一种强大的技术手段。以下是完整的实现方案:
一、基础消息转发实现多继承
1. 快速转发方案(forwardingTargetForSelector:)
// 多继承模拟类
@interface MultiInheritObject : NSObject
@property (nonatomic, strong) NSMutableDictionary *forwardingTargets;
@end
@implementation MultiInheritObject
- (instancetype)init {
self = [super init];
if (self) {
_forwardingTargets = [NSMutableDictionary dictionary];
}
return self;
}
// 添加转发目标
- (void)addForwardingTarget:(id)target forProtocol:(Protocol *)protocol {
NSString *protocolName = NSStringFromProtocol(protocol);
self.forwardingTargets[protocolName] = target;
}
// 核心转发方法
- (id)forwardingTargetForSelector:(SEL)aSelector {
// 遍历所有转发目标,找到能响应此方法的对象
for (id target in self.forwardingTargets.allValues) {
if ([target respondsToSelector:aSelector]) {
return target;
}
}
return [super forwardingTargetForSelector:aSelector];
}
@end
2. 完整使用示例
// 定义两个"父类"
@interface Animal : NSObject
- (void)eat;
- (void)sleep;
@end
@implementation Animal
- (void)eat { NSLog(@"Animal eating"); }
- (void)sleep { NSLog(@"Animal sleeping"); }
@end
@interface Machine : NSObject
- (void)work;
- (void)repair;
@end
@implementation Machine
- (void)work { NSLog(@"Machine working"); }
- (void)repair { NSLog(@"Machine repairing"); }
@end
// 使用多继承模拟
MultiInheritObject *multiObj = [[MultiInheritObject alloc] init];
Animal *animal = [[Animal alloc] init];
Machine *machine = [[Machine alloc] init];
[multiObj addForwardingTarget:animal forProtocol:@protocol(NSObject)];
[multiObj addForwardingTarget:machine forProtocol:@protocol(NSObject)];
// 现在multiObj可以调用两个"父类"的方法
[multiObj eat]; // 输出: Animal eating
[multiObj work]; // 输出: Machine working
OC消息转发实现多继承
核心实现方案
1. 快速转发方案
- (id)forwardingTargetForSelector:(SEL)aSelector {
for (id target in self.forwardingTargets) {
if ([target respondsToSelector:aSelector]) {
return target;
}
}
return [super forwardingTargetForSelector:aSelector];
}
2. 完整消息转发方案
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
for (id parent in self.parentObjects) {
if ([parent respondsToSelector:aSelector]) {
return [parent methodSignatureForSelector:aSelector];
}
}
return [super methodSignatureForSelector:aSelector];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation {
for (id parent in self.parentObjects) {
if ([parent respondsToSelector:anInvocation.selector]) {
[anInvocation invokeWithTarget:parent];
return;
}
}
[super forwardInvocation:anInvocation];
}
实际应用场景
1. 模块解耦
// 服务定位器模式
- (id)forwardingTargetForSelector:(SEL)aSelector {
for (id service in self.services.allValues) {
if ([service respondsToSelector:aSelector]) {
return service;
}
}
return [super forwardingTargetForSelector:aSelector];
}
2. 容错处理
// 安全的Delegate包装器
- (id)forwardingTargetForSelector:(SEL)aSelector {
if ([self.originalDelegate respondsToSelector:aSelector]) {
return self.originalDelegate;
}
return nil; // 防止崩溃
}
3. AOP编程
// 性能监控
- (id)forwardingTargetForSelector:(SEL)aSelector {
CFTimeInterval start = CACurrentMediaTime();
id result = [self.originalTarget forwardingTargetForSelector:aSelector];
CFTimeInterval duration = (CACurrentMediaTime() - start) * 1000;
NSLog(@"%@ 执行时间: %.2fms", NSStringFromSelector(aSelector), duration);
return result;
}
Swift多继承替代方案
1. 协议 + 协议扩展
protocol Flyable { func fly() }
protocol Swimmable { func swim() }
extension Flyable { func fly() { print("默认飞行") } }
extension Swimmable { func swim() { print("默认游泳") } }
class SuperAnimal: Flyable, Swimmable {
// 自动获得默认实现
}
2. 协议组合
typealias Amphibious = Flyable & Swimmable
func handleAmphibious(_ creature: Amphibious) {
creature.fly()
creature.swim()
}
OC与Swift协议对比
OC协议局限:
- 无默认实现:必须实现所有协议方法
- 无关联类型:无法表达泛型概念
- 编译时限制:缺少协议扩展能力
Swift协议优势:
- 协议扩展:提供默认实现
- 关联类型:支持泛型协议
- 类型安全:编译时检查
在 Swift 中,泛型协议主要通过以下两种方式实现:
1. 关联类型协议 - 主要的泛型协议
这是 Swift 中最接近"泛型协议"的概念,使用 associatedtype 关键字:
// 定义泛型协议
protocol Container {
associatedtype Item
var count: Int { get }
mutating func append(_ item: Item)
subscript(i: Int) -> Item { get }
}
// 实现协议时指定具体类型
struct IntStack: Container {
typealias Item = Int // 明确指定关联类型
private var items: [Item] = []
var count: Int { items.count }
mutating func append(_ item: Item) {
items.append(item)
}
subscript(i: Int) -> Item {
return items[i]
}
}
// 或者让编译器自动推断
struct GenericStack<Element>: Container {
// 编译器自动推断 Item = Element
private var items: [Element] = []
var count: Int { items.count }
mutating func append(_ item: Element) {
items.append(item)
}
subscript(i: Int) -> Element {
return items[i]
}
}
2. 带 Self 要求的协议
使用 Self 关键字来引用实现类型:
protocol Equatable {
static func == (lhs: Self, rhs: Self) -> Bool
}
protocol Comparable: Equatable {
static func < (lhs: Self, rhs: Self) -> Bool
static func <= (lhs: Self, rhs: Self) -> Bool
static func >= (lhs: Self, rhs: Self) -> Bool
static func > (lhs: Self, rhs: Self) -> Bool
}
// 实现
struct Person: Comparable {
let name: String
let age: Int
static func == (lhs: Person, rhs: Person) -> Bool {
return lhs.name == rhs.name && lhs.age == rhs.age
}
static func < (lhs: Person, rhs: Person) -> Bool {
return lhs.age < rhs.age
}
}
高级用法
关联类型约束
protocol SuffixableContainer: Container {
associatedtype Suffix: SuffixableContainer where Suffix.Item == Item
func suffix(_ size: Int) -> Suffix
}
// 实现
struct Stack<Element>: SuffixableContainer {
private var items: [Element] = []
// Container 要求
var count: Int { items.count }
mutating func append(_ item: Element) {
items.append(item)
}
subscript(i: Int) -> Element {
return items[i]
}
// SuffixableContainer 要求
func suffix(_ size: Int) -> Stack {
let result = Stack()
result.items = Array(items.suffix(size))
return result
}
}
协议组合与泛型
protocol Identifiable {
associatedtype ID: Hashable
var id: ID { get }
}
protocol Named {
var name: String { get }
}
// 使用泛型约束
func processItems<T: Identifiable & Named>(_ items: [T]) where T.ID == Int {
for item in items {
print("Item \(item.id): \(item.name)")
}
}
// 或者使用 some 关键字 (Swift 5.7+)
func getItem() -> some Identifiable & Named {
return SomeConcreteType()
}
使用场景对比
| 特性 | 关联类型协议 | Self 要求协议 |
|---|---|---|
| 适用场景 | 容器、集合、数据源 | 比较、序列化、拷贝 |
| 灵活性 | 高,可适配多种类型 | 中等,限于自身类型 |
| 复杂度 | 较高 | 相对简单 |
实际应用示例
// 网络请求泛型协议
protocol APIRequest {
associatedtype Response: Decodable
var endpoint: String { get }
var method: HTTPMethod { get }
func decode(_ data: Data) throws -> Response
}
// 具体实现
struct UserRequest: APIRequest {
typealias Response = User
let endpoint = "/users"
let method: HTTPMethod = .get
func decode(_ data: Data) throws -> User {
return try JSONDecoder().decode(User.self, from: data)
}
}
// 使用泛型网络客户端
class APIClient {
func send<T: APIRequest>(_ request: T) async throws -> T.Response {
// 网络请求实现...
let data = Data()
return try request.decode(data)
}
}
重要限制
Swift 的泛型协议(关联类型协议)不能直接用作类型:
// ❌ 错误:不能直接使用
let container: Container = SomeContainer()
// ✅ 正确:使用泛型约束
func processContainer<C: Container>(_ container: C) where C.Item == Int {
// 处理容器
}
总结:Swift 中的"泛型协议"主要是通过 关联类型 实现的,它提供了强大的类型抽象能力,但在使用时需要注意类型擦除等高级技巧。
要点
- OC多继承:通过消息转发机制模拟,有性能开销
- Swift多继承:通过协议+协议扩展实现,类型安全
- 实际应用:模块解耦、容错处理、AOP编程
- 选择建议:OC用于运行时灵活,Swift用于类型安全
核心区别:OC是"接口多继承",Swift是"实现多继承"