标签: combine

Swift Property Wrapper是否可以引用其包装的财产所有者?

从Swift的属性包装器中,您可以有人引用拥有被包装属性的类实例或被删除的实例吗?使用self显然不起作用,也不起作用super

我试图传递self给属性包装器,init()但这也不起作用,因为self在评估Configuration时on 尚未定义@propertywrapper

我的用例在用于管理大量设置或配置的类中。如果有任何属性更改,我只想通知感兴趣的人某些更改。他们实际上并不需要只知道哪个值,因此实际上不必为每个属性使用KVOPublisher

属性包装器看起来很理想,但是我不知道如何传递对包装器可以回调的拥有实例的某种引用。

参考文献:

SE-0258

enum PropertyIdentifier {
  case backgroundColor
  case textColor
}

@propertyWrapper
struct Recorded<T> {
  let identifier:PropertyIdentifier
  var _value: T

  init(_ identifier:PropertyIdentifier, defaultValue: T) {
    self.identifier = identifier
    self._value = defaultValue
  }

  var value: T {
    get {  _value }
    set {
      _value = newValue

      // How to callback to Configuration.propertyWasSet()?
      //
      // [self/super/...].propertyWasSet(identifier)
    }
  } …
Run Code Online (Sandbox Code Playgroud)

swift swift5 combine

8
推荐指数
2
解决办法
696
查看次数

将订阅存储到订阅集中的原因是什么?

组合订阅示例代码片段全部将生成的订阅存储到集合subscriptions

private var subscriptions = Set<AnyCancellable>()
Run Code Online (Sandbox Code Playgroud)

为什么我们需要这样做?

future
  .sink(receiveCompletion: { print($0) }, receiveValue: { print($0) }) 
  .store(in: &subscriptions)
Run Code Online (Sandbox Code Playgroud)

swift combine

8
推荐指数
1
解决办法
1931
查看次数

组合和 RxSwift 有什么区别?

不知道是否有一个优秀的文档来展示Combine和RxSwift之间的区别?

快速学习对我来说有好处,Combine因为我已经对这方面有了很好的了解RxSwift

rx-swift combine

8
推荐指数
1
解决办法
5735
查看次数

致命错误:UnsafeRawBufferPointer 从 Core Data/NSFetchedResultsController 删除对象时计数为负

这是我第一次使用 AppKit 和NSTableView. 它由NSFetchedResultsController核心数据支持。当数据集发生更改时,Notification将发送:

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
    guard let links = self.fetchedResultsController.fetchedObjects else {
        return
    }

    if self.viewContext.hasChanges {
        try? self.viewContext.save()
    }
        
    self._links = links
    NotificationCenter.default.post(name: .reloadLinkList, object: nil)
}
Run Code Online (Sandbox Code Playgroud)
NotificationCenter.default.publisher(for: .reloadLinkList).receive(on: RunLoop.main).sink { notification in
    self.list.tableView.reloadData()
    self.list.linksModel.selectedRows = IndexSet([])
}
.store(in: &cancellables)
Run Code Online (Sandbox Code Playgroud)

这对于插入和更新数据非常有用。当我尝试删除某些内容时,我得到:

Thread 1: Fatal error: UnsafeRawBufferPointer with negative count
Run Code Online (Sandbox Code Playgroud)

删除选定对象的代码如下:

Thread 1: Fatal error: UnsafeRawBufferPointer with negative count …
Run Code Online (Sandbox Code Playgroud)

macos appkit nsfetchedresultscontroller swift combine

8
推荐指数
1
解决办法
2167
查看次数

swift 组合 `.collect` 方法在哪个线程上发出?

.collectSwift 的组合中的操作将在哪个线程上发出预期的线程?

具体来说,我在第二个前提条件中看到此代码崩溃,但在第一个前提条件中没有崩溃:

return Publishers.MergeMany(publishers)
    .handleEvents(receiveOutput: { _ in
        precondition(Thread.isMainThread) // <- This is fine
    })
    .collect()
    .handleEvents(receiveOutput: { _ in
        precondition(Thread.isMainThread) // <- Crash is here
    })
Run Code Online (Sandbox Code Playgroud)

就好像该.collect操作正在选择一个不同的线程来使用,即使最终的发布者必须MergeMany在主线程上发出。我通过从 Firebase 上传的崩溃日志推断出此行为。谁能解释这种观察到的行为?

swift combine

8
推荐指数
1
解决办法
124
查看次数

Swift 结合发布者与完成处理程序以及何时取消

我知道发布者通常比闭包更强大,但是我想询问并讨论一个具体的例子:

func getNotificationSettingsPublisher() -> AnyPublisher<UNNotificationSettings, Never> {
   let notificationSettingsFuture = Future<UNNotificationSettings, Never> { (promise) in
      UNUserNotificationCenter.current().getNotificationSettings { (settings) in
         promise(.success(settings))
      }
   }
   return notificationSettingsFuture.eraseToAnyPublisher()
}
Run Code Online (Sandbox Code Playgroud)

我认为这是 Future 发布者的一个有效示例,可以在这里使用它而不是使用完成处理程序。让我们用它做点什么:

func test() {
    getNotificationSettingsPublisher().sink { (notificationSettings) in
       // Do something here        
    }
}
Run Code Online (Sandbox Code Playgroud)

这有效,但是它会告诉我 sink ( AnyCancellable)的结果未使用。因此,每当我尝试获取一个值时,我都需要存储可取消对象或分配它,直到我获得一个值。

是否有类似 sinkOnce 或可取消项的自动销毁之类的东西?有时我不需要取消的任务。但是我可以这样做:

func test() {
   self.cancellable = getNotificationSettingsPublisher().sink { [weak self] (notificationSettings) in
      self?.cancellable?.cancel()
      self?.cancellable = nil
   }
}
Run Code Online (Sandbox Code Playgroud)

所以一旦我收到一个值,我就会取消订阅。(我猜我可以在水槽的完成关闭中做同样的事情)。

这样做的正确方法是什么?因为如果我使用一个闭包,它会被调用多少次函数被调用,如果它只被调用一次,那么我不需要取消任何东西。

你会说普通的完成处理程序可以用组合代替吗?如果是这样,你会如何处理接收一个值然后取消?

最后但并非最不重要的是,调用完成,我还需要取消订阅吗?我至少需要更新可取消并将其设置为 nil 对吗?我假设将订阅存储在一个集合中是为了长期运行的订阅,但是单值订阅呢?

谢谢

swift combine

7
推荐指数
1
解决办法
3143
查看次数

如何向 PassthroughSubject 发送错误?

let myPassthrough = PassthroughSubject<String, Error>()
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用以下方法向传递主题发送值send

myPassthrough.send("abc")
Run Code Online (Sandbox Code Playgroud)

我如何发送失败?


我试过:

myPassthrough.send(Fail(error: error))
myPassthrough.send(completion: Fail(error: error))
myPassthrough.send(completion: Just(error))
myPassthrough.send(completion: error)
Run Code Online (Sandbox Code Playgroud)

他们都没有编译

swift combine

7
推荐指数
1
解决办法
1848
查看次数

我可以将 AnyPublisher 转换为 Published.Publisher 吗?

所以我有一个 type 值AnyPublisher<Foo, Error>,我需要将其转换为Published<Foo>.Publisher这样我可以将其用作@Published

所以我的想法是我有一个 MVVM 架构

struct SwiftUIView: View {
  @ObservedObject var viewModel: MyViewModel
  var body: some View {
    Text(/*Foo has a title, how do I access it? */)
  }
  
}
class MyViewModel: ObservableObject {
  var cellModels: AnyPublisher<Foo, Error>
  // so the idea is to have and then access it in swiftUI view via viewModel.cellModels2.title
  @Published cellModels2 = convert_somehow_to_publisher(cellModels)
}
Run Code Online (Sandbox Code Playgroud)

显然我不能使用 viewModel.cellModels

那可能吗?

combine

7
推荐指数
1
解决办法
1741
查看次数

SwiftUI 组合:@Published 仅适用于类的属性

我有以下代码,但收到消息错误:

“wrappedValue”不可用:@Published 仅适用于类的属性

//*
/**
Chat
Created on 29/07/2020
*/

import SwiftUI

let lightGreyColor = Color(red: 239.0/255.0, green: 243.0/255.0, blue: 244.0/255.0, opacity: 1.0)

struct ConnectionView: View {
    @ObservedObject var keyboardResponder = KeyboardResponder()
    @ObservedObject var viewModel = ConnectionVM()
//    @State var uuid1: String = ""
//    @State var uuid2: String = ""
    @State var authenticationDidFail: Bool = false
    
    var body: some View {
        return VStack {
            WelcomeText()
            LogoImage()
            UUIDTextField(uuid: viewModel.uuid1)
            UUIDTextField(uuid: viewModel.uuid2)
            if authenticationDidFail {
                Text("Information not correct. Try again.")
                .offset(y: …
Run Code Online (Sandbox Code Playgroud)

ios swiftui combine

7
推荐指数
1
解决办法
7513
查看次数

在需要@Binding的地方传递@Published(SwiftUI,Combine)

一个ViewModel类有一个sourceProperty正在由 编辑的TextField。该属性是@Published. 我想将它Logic传递给具有Binding<String>. 该类将监听更改sourceProperty,对其做出反应并将其输出设置为属性@Published output

如何@Published sourceProperty作为初始化参数传递给类Logic

相关代码:

final class ViewModel {
    @Published var sourceProperty: String = ""
    private var logic: Logic?

    init() {
        self.logic = Logic(data: $sourceProperty)
        $logic.output.sink({result in 
            print("got result: \(result)")
        })
    }

}

final class Logic: ObservableObject {
    private var bag = Set<AnyCancellable>()
    @Published var output: String = ""
    @Binding var data: String
    init(data: Binding<String>) {
        self._data …
Run Code Online (Sandbox Code Playgroud)

data-binding binding publisher swiftui combine

7
推荐指数
1
解决办法
1万
查看次数