首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为NotificationToken观察commitWrite(withoutNotifying:[令牌])的相同线程

为NotificationToken观察commitWrite(withoutNotifying:[令牌])的相同线程
EN

Stack Overflow用户
提问于 2018-02-07 05:21:22
回答 2查看 1.1K关注 0票数 0

问题是如何使对象在同一个线程中观察和commitWrite。

  1. 我想观察线程中的对象正在变化。根据本文,使用Swift的后台线程的领域通知很容易实现。
  2. 然而,存在一个问题。在某些情况下我不想通知你。所以我使用realm.commitWrite(withoutNotifying: [token])来实现commitWrite。

下面的代码是commitWrite,没有通知

我想用BackgroundWorker在同一个线程中运行这段代码

代码语言:javascript
复制
let realm = try! Realm()
realm.beginWrite()
realm.add(object, update: true)
try! realm.commitWrite(withoutNotifying: [notificationToken])

这是王国的物体观察。它将在子线程中运行(BackgroundWorker来自上面的链接)

代码语言:javascript
复制
var worker: BackgroundWorker?
private func registerLocalDatabaseStep1() {
    worker = BackgroundWorker()
    worker?.start { [weak self] in
        guard let `self` = self else { return }
        `self`.registerLocalDatabase()
    }
}
private func registerLocalDatabase() {
    let objects = Cream<T>().realm.objects(T.self)
    notificationToken = objects.observe({ [weak self](changes) in
        guard let `self` = self else { return }

        switch changes {
        case .initial(_):
            break
        case .update(let collection, _, let insertions, let modifications):
            //do something
        case .error(_):
            break
        }
    })
}

我从上面的链接中发布了BackgroundWorker,以使它更容易阅读。

代码语言:javascript
复制
class BackgroundWorker: NSObject {
  private var thread: Thread!
  private var block: (()->Void)!

  internal func runBlock() { block() }

  internal func start(_ block: @escaping () -> Void) {
    self.block = block

    let threadName = String(describing: self)
      .components(separatedBy: .punctuationCharacters)[1]

    thread = Thread { [weak self] in
      while (self != nil && !self!.thread.isCancelled) {
        RunLoop.current.run(
          mode: RunLoopMode.defaultRunLoopMode, 
          before: Date.distantPast)
      }
      Thread.exit()
    }
    thread.name = "\(threadName)-\(UUID().uuidString)"
    thread.start()

    perform(#selector(runBlock),
      on: thread,
      with: nil,
      waitUntilDone: false,
      modes: [RunLoopMode.defaultRunLoopMode.rawValue])
  }

  public func stop() {
    thread.cancel()
  }
}

根据领域API

问题是如何使对象在同一个线程中观察和commitWrite。

我想使用realm.commitWrite(withoutNotifying方法在同一个线程中运行registerLocalDatabase()

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-07 06:02:53

答案是,在同一个线程中运行代码很容易。

更新BackgroundWorker

代码语言:javascript
复制
class BackgroundWorker: NSObject {
    private var thread: Thread!
    private var block: (()->Void)!

    @objc internal func runBlock() { block() }

    ///create a thread
    private func createThread() {
        let threadName = String(describing: self)
            .components(separatedBy: .punctuationCharacters)[1]

        thread = Thread { [weak self] in
            while (self != nil && !self!.thread.isCancelled) {
                // Poll to see if thread was canceled. If using
                // multiple threads `.distantPast` will cause 100% CPU
                // usage. If using `.distantFuture` the thread will never exit.
                RunLoop.current.run(
                    mode: RunLoopMode.defaultRunLoopMode,
                    before: .now + 30)
            }
            Thread.exit()
        }
        thread.name = "\(threadName)-\(UUID().uuidString)"
        thread.start()
    }

    internal func start(_ block: @escaping () -> Void) {
        self.block = block

        //if thread is nil, create a new one. Otherwise run block in the same thread!!!!
        if thread == nil {
            createThread()
        }

        perform(#selector(runBlock),
                on: thread,
                with: nil,
                waitUntilDone: false,
                modes: [RunLoopMode.defaultRunLoopMode.rawValue])
    }

    public func stop() {
        thread.cancel()
    }
}

因此,如何执行,使用相同的worker of BackgroundWorker

代码语言:javascript
复制
`self`.worker?.start {
    let realm = try! Realm()
    realm.beginWrite()
    realm.add(object, update: true)
    realm.commitWrite(withoutNotifying: [`self`.notificationToken])
}
票数 0
EN

Stack Overflow用户

发布于 2018-02-07 05:34:36

我相信您可以将提交commitWrite移动到主线程,如下所示:

代码语言:javascript
复制
DispatchQueue.main.sync {
    let realm = try! Realm()
    realm.beginWrite()
    realm.add(object, update: true)
    try! realm.commitWrite(withoutNotifying: [notificationToken])
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48656511

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档