首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当委托字段未被称为“委托”时,实现“`DelegateProxy`”(RxSwift/RxCocoa)

当委托字段未被称为“委托”时,实现“`DelegateProxy`”(RxSwift/RxCocoa)
EN

Stack Overflow用户
提问于 2019-01-19 10:42:20
回答 1查看 1.1K关注 0票数 0

我需要一些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."中失败--也许它甚至与委托字段名无关,但这是我能找到的与正常工作的代理的唯一不同之处。

更新: Ha!我只是注意到错误消息说的是PKPhysicsWorld,而不是SKPhysicsWorld。所以我的假设是,这与object in DelegateProxyFactory.createProxy是一个PKPhysicsWorld而不是SKPhysicsWorld_factories[ObjectIdentifier(mirror.subjectType)]返回nil的事实有关。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-20 13:55:25

之所以会出现此错误,是因为您的registerKnownImplementations()函数没有运行。

以下要点应该有效:https://gist.github.com/dtartaglia/9f1f937628504ca56dbb1aac7d91df2b

代码也在下面,但要点可以保持最新:

代码语言:javascript
复制
//
//  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>])] = [:]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54266227

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档