如何在 Combine in Swift 中的订阅者中引用自己

How to reference self in a Subscriber in Combine in Swift

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

这是订阅...

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

编译器告诉我的是 Use of unresolved identifier 'self'。 太晚了,我有点累了,有人知道吗? Xcode Catalina beta 5 上的 11 beta 5 顺便说一句...

完整文件:

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( {
        ([=12=].object as! Data)
    } )
    .sink(receiveValue: {
        self.interpretIncoming(data: [=12=])
    })

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 在您调用的上下文中不存在。有多种补救方法包括将 interpretIncoming 定义为闭包变量或将其设为 class 方法并根据需要调用。

除了 self 这个词,你问题中的所有内容都是转移注意力的问题。你是说:

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

您不能在 属性 声明的初始化程序中提及 self,因为 self 是我们正在初始化的;还没有self

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