You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DelegateProxy(RxSwift/RxCocoa)实现求助:非默认代理字段及类型问题

How to Implement DelegateProxy for Non-Standard Delegate Fields + Fixing PKPhysicsWorld Factory Issues

Let's break down your problem into two key parts: handling non-default delegate property names (like contactDelegate instead of delegate) and resolving the PKPhysicsWorld factory missing error.

1. Fixing the Non-Standard Delegate Field Mapping

When your target object uses a delegate property that's not named delegate (like SKPhysicsWorld's contactDelegate), you can't rely on the default DelegateProxy behavior. You need to explicitly map the proxy to the correct property in your DelegateProxy subclass:

Step 1: Override the delegate Computed Property

In your RxSKPhysicsContactDelegateProxy, override the delegate property to directly interact with the target's contactDelegate:

public override var delegate: AnyObject? {
    get {
        guard let world = self.parentObject as? SKPhysicsWorld else { return nil }
        return world.contactDelegate
    }
    set {
        guard let world = self.parentObject as? SKPhysicsWorld else { return }
        world.contactDelegate = newValue as? SKPhysicsContactDelegate
        // Sync with DelegateProxy's internal forwarding logic
        self._setForwardToDelegate(newValue, retainDelegate: true)
    }
}

Step 2: Initialize the Proxy Correctly

Make sure when your proxy is created, it replaces the original contactDelegate so all events flow through the Rx proxy:

public init(parentObject: SKPhysicsWorld) {
    super.init(parentObject: parentObject, delegateProxy: RxSKPhysicsContactDelegateProxy.self)
    // Preserve the original delegate and set self as the new contactDelegate
    let originalDelegate = parentObject.contactDelegate
    self.setForwardToDelegate(originalDelegate, retainDelegate: true)
    parentObject.contactDelegate = self
}

2. Resolving the PKPhysicsWorld Factory Error

The error mentions PKPhysicsWorld because SpriteKit uses this private subclass of SKPhysicsWorld under the hood. Your current factory only registers for SKPhysicsWorld.self, so it can't find a proxy for the runtime type PKPhysicsWorld.

Option 1: Register the Factory for the Private Subclass (Runtime Hack)

Since PKPhysicsWorld is private, you can't reference it directly, but you can use runtime APIs to register the proxy for it:

// First, register for the public SKPhysicsWorld
DelegateProxyFactory.registerProxy {
    RxSKPhysicsContactDelegateProxy(parentObject: $0)
} for: SKPhysicsWorld.self

// Then register for the private PKPhysicsWorld using NSClassFromString
if let pkPhysicsWorldClass = NSClassFromString("PKPhysicsWorld") {
    DelegateProxyFactory.registerProxy { object in
        guard let world = object as? SKPhysicsWorld else {
            fatalError("Expected SKPhysicsWorld or its subclass")
        }
        return RxSKPhysicsContactDelegateProxy(parentObject: world)
    } for: pkPhysicsWorldClass
}

Option 2: Use a Generic Factory That Matches Subclasses

Alternatively, you can adjust your factory registration to accept any instance of SKPhysicsWorld (including its subclasses) by using a more flexible registration block:

DelegateProxyFactory.registerProxy { object in
    guard let world = object as? SKPhysicsWorld else {
        fatalError("Object must be an SKPhysicsWorld instance")
    }
    return RxSKPhysicsContactDelegateProxy(parentObject: world)
} for: SKPhysicsWorld.self

This works because DelegateProxyFactory will use this factory for any object that is an instance of SKPhysicsWorld (including private subclasses like PKPhysicsWorld).

Final Checks

  • Ensure your SKPhysicsWorld extension conforms to HasDelegate correctly:
    extension SKPhysicsWorld: HasDelegate {
        public typealias Delegate = SKPhysicsContactDelegate
    }
    
  • Verify that all delegate methods you want to observe are properly forwarded in your RxSKPhysicsContactDelegateProxy (e.g., didBegin(_:) and didEnd(_:)).

内容的提问来源于stack exchange,提问作者Maxim Volgin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:02:15