当委托字段不被称为 `delegate` 时实现 `DelegateProxy` (RxSwift/RxCocoa)
Posted
技术标签:
【中文标题】当委托字段不被称为 `delegate` 时实现 `DelegateProxy` (RxSwift/RxCocoa)【英文标题】:Implementing `DelegateProxy` (RxSwift/RxCocoa) when delegate field is not called `delegate` 【发布时间】:2019-01-19 10:42:20 【问题描述】:我需要一些有关DelegateProxy
实施的帮助。具体来说,当委托字段的名称与简单的delegate
不同时,实现它的正确方法是什么?如在SKPhysicsContactDelegate
中称为contactDelegate
。我尝试定义一个计算值delegate
,但它没有成功 - https://github.com/maxvol/RxSpriteKit/blob/master/Proxy/RxSKPhysicsContactDelegateProxy.swift
"DelegateProxy has no factory of <PKPhysicsWorld: 0x280b18990>. Implement DelegateProxy subclass for <PKPhysicsWorld: 0x280b18990> first."
失败
也许它甚至与委托字段名称无关,但这是我能找到的与正常工作的代理的唯一区别。
更新:哈!我刚刚注意到错误消息说PKPhysicsWorld
,而不是SKPhysicsWorld
。所以我的假设是,这与DelegateProxyFactory.createProxy
中的object
是PKPhysicsWorld
而不是SKPhysicsWorld
和_factories[ObjectIdentifier(mirror.subjectType)]
返回nil
的事实有关。
【问题讨论】:
【参考方案1】:您收到该错误的原因是您的 registerKnownImplementations()
函数没有运行。
以下要点应该有效:https://gist.github.com/dtartaglia/9f1f937628504ca56dbb1aac7d91df2b
代码也在下面,但要点可以保持最新:
//
// 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>])] = [:]
【讨论】:
不幸的是,没有任何区别。我的registerKnownImplementations()
被调用,但里面的内容 (self.register ...
) 失败了。
4.4.0;我的假设是这与DelegateProxyFactory.createProxy
中的object
是PKPhysicsWorld
而不是SKPhysicsWorld
和_factories[ObjectIdentifier(mirror.subjectType)]
返回nil
的事实有关。
我刚刚在开发者论坛forums.developer.apple.com/thread/96994 中找到了这个。你是对的,这意味着你不能实现委托代理。还有其他方法,我会在今天晚些时候更新我的答案。
感谢您找到该主题。期待你的更新!
你去。老式的方式。 :-)以上是关于当委托字段不被称为 `delegate` 时实现 `DelegateProxy` (RxSwift/RxCocoa)的主要内容,如果未能解决你的问题,请参考以下文章