【问题标题】:How to reference self in a Subscriber in Combine in Swift如何在 Swift 中的 Combine 中的订阅者中引用 self
【发布时间】:2019-08-10 22:45:46
【问题描述】:

刚刚开始使用 Combine 并遇到了一个问题,当它从 Publisher 接收到一个值时,我需要在我的类中调用一个方法,在本例中是来自 NotificationCenterNotification...

这是订阅...

let subscribe = NotificationCenter.default.publisher(for: Notification.Name(rawValue: "LocalTalkNotificationReceivedData"), object: nil)
    .map( {
        ($0.object as! Data)
    } )
    .sink(receiveValue: {
        self.interpretIncoming(data: $0)
    })

编译器告诉我的是Use of unresolved identifier 'self'。 时间不早了,有点累了,有大神知道吗? Xcode 11 beta 5 on Catalina beta 5 btw...

完整文件:

import Foundation
import Combine
import SwiftUI

public class MessageData: ObservableObject, Identifiable {
public var peerData: [Peer] = [Peer]()
public var messageData: [Message] = [Message]()
public var objectWillChange = PassthroughSubject<Void, Never>()
let subscribe = NotificationCenter.default.publisher(for: Notification.Name(rawValue: "LocalTalkNotificationReceivedData"), object: nil)
    .map( {
        ($0.object as! Data)
    } )
    .sink(receiveValue: {
        self.interpretIncoming(data: $0)
    })

init() {
    self.setupDummyData()
}

private func setupDummyData() {
    self.peerData = self.load("peerData.json")
    self.messageData = self.load("messageData.json")
}

func addMessage(message: String, sender: MessageSource, name: String) {
    let newMessage = Message(id: Date().hashValue,
                             content: message,
                             source: sender,
                             correspondent: name)
    self.messageData.append(newMessage)
    self.objectWillChange.send()
}

func load<T: Decodable>(_ filename: String, as type: T.Type = T.self) -> T {
    let data: Data

    guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
        else {
            fatalError("Couldn't find \(filename) in main bundle.")
    }

    do {
        data = try Data(contentsOf: file)
    } catch {
        fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
    }

    do {
        let decoder = JSONDecoder()
        return try decoder.decode(T.self, from: data)
    } catch {
        fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
    }
}

func interpretIncoming(data sent: Data) {
    do {
        let receivedTransmission = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(sent) as! [String: Any]
        self.addMessage(message: receivedTransmission["messagePayload"] as! String,
                        sender: .them,
                        name: receivedTransmission["messageSender"] as! String)
    } catch {
        print("FAILED DECODING THING")
    }
}

}

【问题讨论】:

  • 显示更多代码。 self 是否存在取决于你的代码在哪里。与Combine无关。
  • 好的,添加完整的文件

标签: swift nsnotificationcenter publisher subscriber combine


【解决方案1】:

除了self 这个词之外,您问题中的所有内容都是一个红鲱鱼。你是说:

class MessageData: ObservableObject, Identifiable {
    let subscribe = ... self ...
}

你不能在属性声明的初始化器中提到self,因为self是我们正在初始化的过程;还没有self

这里的一个简单解决方案可能是将let subscribe 更改为lazy var subscribe,但是您必须在实际代码中询问subscribe 的值才能进行初始化。但是,还有许多其他可能的方法。

【讨论】:

    【解决方案2】:

    Self 在您调用的上下文中不存在。解决这个问题的方法有很多,包括将interpretIncoming定义为一个闭包变量或使其成为类方法并根据需要调用。

    【讨论】:

    • 有趣。使其成为类方法并没有帮助,因为我正在改变实例的状态。你能告诉我更多关于另一个建议的信息吗,我不太明白你的意思?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-06
    相关资源
    最近更新 更多