[英]Implementing `DelegateProxy` (RxSwift/RxCocoa) when delegate field is not called `delegate`
I need some help with DelegateProxy
implementation. 我需要有关
DelegateProxy
实施的帮助。 Specifically, what is the proper way of implementing it when the delegate field has different name than simply delegate
? 具体来说,当委托字段的名称不同于简单
delegate
名称时,实现它的正确方法是什么? Such as in SKPhysicsContactDelegate
it is called contactDelegate
. 例如在
SKPhysicsContactDelegate
它称为contactDelegate
。 I tried defining a computed value delegate
, but it did not do the trick - https://github.com/maxvol/RxSpriteKit/blob/master/Proxy/RxSKPhysicsContactDelegateProxy.swift 我尝试定义一个计算值
delegate
,但没有成功-https: //github.com/maxvol/RxSpriteKit/blob/master/Proxy/RxSKPhysicsContactDelegateProxy.swift
It fails with "DelegateProxy has no factory of <PKPhysicsWorld: 0x280b18990>. Implement DelegateProxy subclass for <PKPhysicsWorld: 0x280b18990> first."
它失败,因为
"DelegateProxy has no factory of <PKPhysicsWorld: 0x280b18990>. Implement DelegateProxy subclass for <PKPhysicsWorld: 0x280b18990> first."
Perhaps it is not even related to the delegate field name, but this is the only difference with properly working proxies I could find. 也许它甚至与委托字段名称都不相关,但这是我能找到的与正常工作的代理唯一的区别。
UPDATE: Ha! 更新:哈! I just noticed that error message says
PKPhysicsWorld
, not SKPhysicsWorld
. 我只是注意到错误消息显示
PKPhysicsWorld
而不是SKPhysicsWorld
。 So my hypothesis is that it has something to do with the fact that object
in DelegateProxyFactory.createProxy
is a PKPhysicsWorld
instead of SKPhysicsWorld
and _factories[ObjectIdentifier(mirror.subjectType)]
returns nil
. 因此,我的假设是,与
DelegateProxyFactory.createProxy
中的object
是PKPhysicsWorld
而不是SKPhysicsWorld
且_factories[ObjectIdentifier(mirror.subjectType)]
返回nil
。
The reason you are getting that error is because your registerKnownImplementations()
function isn't getting run. 您收到该错误的原因是因为您的
registerKnownImplementations()
函数未运行。
The following gist should work: https://gist.github.com/dtartaglia/9f1f937628504ca56dbb1aac7d91df2b 以下要点应该起作用: https : //gist.github.com/dtartaglia/9f1f937628504ca56dbb1aac7d91df2b
The code is also below but the gist can be kept up to date: 代码也在下面,但要点可以保持最新:
//
// SKPhysicsWorld+Rx.swift
//
// Created by Daniel Tartaglia on 21 Jan 2019.
// Copyright © 2019 Daniel Tartaglia. MIT License.
//
import RxSwift
import SpriteKit
public
extension Reactive where Base: SKPhysicsWorld {
var didBegin: Observable<SKPhysicsContact> {
return Observable.create { observer in
physicsContatctDelegatesLock.lock(); defer { physicsContatctDelegatesLock.unlock() }
let uuid = UUID()
if let (delegate, beginners, enders) = physicsContatctDelegates[self.base] {
var new = beginners
new[uuid] = observer
physicsContatctDelegates[self.base] = (delegate, new, enders)
}
else {
let delegate = PhysicsContactDelegate(for: self.base)
self.base.contactDelegate = delegate
physicsContatctDelegates[self.base] = (delegate, [uuid: observer], [:])
}
return Disposables.create {
physicsContatctDelegatesLock.lock(); defer { physicsContatctDelegatesLock.unlock() }
let (delegate, beginners, enders) = physicsContatctDelegates[self.base]!
var new = beginners
new.removeValue(forKey: uuid)
if new.isEmpty && enders.isEmpty {
physicsContatctDelegates.removeValue(forKey: self.base)
}
else {
physicsContatctDelegates[self.base] = (delegate, new, enders)
}
}
}
}
var didEnd: Observable<SKPhysicsContact> {
return Observable.create { observer in
physicsContatctDelegatesLock.lock(); defer { physicsContatctDelegatesLock.unlock() }
let uuid = UUID()
if let (delegate, beginners, enders) = physicsContatctDelegates[self.base] {
var new = enders
new[uuid] = observer
physicsContatctDelegates[self.base] = (delegate, beginners, new)
}
else {
let delegate = PhysicsContactDelegate(for: self.base)
self.base.contactDelegate = delegate
physicsContatctDelegates[self.base] = (delegate, [:], [uuid: observer])
}
return Disposables.create {
physicsContatctDelegatesLock.lock(); defer { physicsContatctDelegatesLock.unlock() }
let (delegate, beginners, enders) = physicsContatctDelegates[self.base]!
var new = enders
new.removeValue(forKey: uuid)
if new.isEmpty && enders.isEmpty {
physicsContatctDelegates.removeValue(forKey: self.base)
}
else {
physicsContatctDelegates[self.base] = (delegate, beginners, new)
}
}
}
}
}
private
class PhysicsContactDelegate: NSObject, SKPhysicsContactDelegate {
init(for world: SKPhysicsWorld) {
self.world = world
super.init()
}
func didBegin(_ contact: SKPhysicsContact) {
physicsContatctDelegatesLock.lock(); defer { physicsContatctDelegatesLock.unlock() }
let (_, beginners, _) = physicsContatctDelegates[world]!
for each in beginners.values {
each.onNext(contact)
}
}
func didEnd(_ contact: SKPhysicsContact) {
physicsContatctDelegatesLock.lock(); defer { physicsContatctDelegatesLock.unlock() }
let (_, _, enders) = physicsContatctDelegates[world]!
for each in enders.values {
each.onNext(contact)
}
}
let world: SKPhysicsWorld
}
private let physicsContatctDelegatesLock = NSRecursiveLock()
private var physicsContatctDelegates: [SKPhysicsWorld: (SKPhysicsContactDelegate, [UUID: AnyObserver<SKPhysicsContact>], [UUID: AnyObserver<SKPhysicsContact>])] = [:]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.