Как вызвать метод при утилизации - PullRequest
0 голосов
/ 01 февраля 2019

У меня есть этот фрагмент кода в RxSwift, который оборачивает UDPBroadcastConnection (https://github.com/gunterhager/UDPBroadcastConnection)) Мой вопрос: что мне нужно сделать, чтобы вызвать closeConnection (), когда наблюдаемое расположено?

struct UDPBroadcastResponse {
    let ip: String
    let port: Int
    let message: [UInt8]
}

final class RxBroadcaster: UDPBroadcastConnection {
    let response = PublishSubject<UDPBroadcastResponse>()
    private let disposeBag = DisposeBag()
}

extension RxBroadcaster: ReactiveCompatible {}

extension Reactive where Base: RxBroadcaster {
    func send(message: String) -> Observable<UDPBroadcastResponse> {
        DDLogVerbose("Sending UDP broadcast message: \(message)")
        self.base.sendBroadcast(message)
        return self.base.response
    }
}

extension RxBroadcaster {
    convenience init(port: UInt16) {
        let rely = ReplaySubject<UDPBroadcastResponse>.createUnbounded()
        self.init(port: port) { ip, port, message in
            let response = UDPBroadcastResponse(ip: ip, port: port, message: message)
            // DDLogVerbose("Receiving UDP message: IP: \(response.ip). Port: \(response.port). Message: \(response.message.map{ String(format: "%02X", $0) }.joined())")
            DDLogVerbose("Receiving UDP message: IP: \(response.ip). Port: \(response.port)")
            rely.onNext(response)
        }
        rely.bind(to: self.response).disposed(by: disposeBag)
    }
}

Здесь я вижу пример: http://adamborek.com/practical-introduction-rxswift/ Но я не уверен насчет жизненного цикла задействованных объектов. Вы можете мне помочь? Спасибо за предложения.

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019

Я был бы более склонен к реализации RxBroadcaster следующим образом:

final class RxBroadcaster {
    let response: Observable<UDPBroadcastResponse>

    init(port: UInt16) {
        let _response = PublishSubject<UDPBroadcastResponse>()
        let _connection = UDPBroadcastConnection(port: port, handler: { ipAddress, port, response in
            _response.onNext(UDPBroadcastResponse(ip: ipAddress, port: port, message: response))
        })

        response = _response.asObservable()
        completion = _response.asObserver()
        connection = _connection
    }

    deinit {
        connection.closeConnection()
        completion.onCompleted()
    }

    private let connection: UDPBroadcastConnection
    private let completion: AnyObserver<UDPBroadcastResponse>
}

extension RxBroadcaster: ObserverType {
    public func on(_ event: RxSwift.Event<Data>) {
        guard case let .next(data) = event else { return }
        connection.sendBroadcast(data)
    }
}

Теперь вы можете отправлять данные, просто связываясь с RxBroadcaster myData.bind(to: myBroadcaster) и получать данные, подписавшись на ответ вещателя.Соединение естественно закроется, когда Broadcaster выйдет из области видимости.

Мне немного странно делать оператор вызова / ответа, как вы.Смысл UDP-сокета в том, что вы будете получать сообщения независимо от отправленных вами.

0 голосов
/ 01 февраля 2019

Вы можете использовать оператор do для подключения к событиям жизненного цикла из подписки и выполнения побочных эффектов.Вы можете позвонить do в любой точке цепочки Observable, прежде чем подписываться или связываться.Пример:

rely.do(onDispose: {
    // called as your subscription is being disposed
}).bind(to: self.response).disposed(by: disposeBag)
...