Мне нужна помощь с реализацией 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. Итак, моя гипотеза заключается в том, что это как-то связано с тем фактом, что object в DelegateProxyFactory.createProxy является PKPhysicsWorld, а не SKPhysicsWorld, а _factories[ObjectIdentifier(mirror.subjectType)] возвращает nil.





Причина, по которой вы получаете эту ошибку, заключается в том, что ваша функция 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>])] = [:]
4.4.0; моя гипотеза состоит в том, что это как-то связано с тем фактом, что object в DelegateProxyFactory.createProxy является PKPhysicsWorld, а не SKPhysicsWorld, а _factories[ObjectIdentifier(mirror.subjectType)] возвращает nil.
Я только что нашел это на форумах разработчиков forums.developer.apple.com/thread/96994. Вы правы, и это означает, что вы не можете реализовать делегированный прокси. Есть и другие способы, я обновлю свой ответ позже сегодня.
Спасибо, что нашли эту тему. С нетерпением ждем вашего обновления!
Ну вот. Старомодный способ. :-)
Вау, спасибо. Возможно, было бы предпочтительнее, если бы вы создали пул реквест для моего репо? В противном случае мне придется скопировать и вставить большую часть вашего кода.
Сначала убедитесь, что он работает. Решение может нуждаться в некоторой полировке.
Я только что сделал пул реквест. Спасибо за вклад в сообщество открытого исходного кода!
Идеально! Я объединил его с (предварительным) выпуском 0.0.3, надеюсь, протестирую его в ближайшие несколько дней.
Никакой разницы, к сожалению. Мой
registerKnownImplementations()вызывается, но то, что внутри него (self.register { ... }), не работает.