rubymotion-community / BubbleWrap

Cocoa wrappers and helpers for RubyMotion (Ruby for iOS and OS X) - Making Cocoa APIs more Ruby like, one API at a time. Fork away and send your pull requests
Other
1.18k stars 208 forks source link

KVO changes from background threads #416

Closed jonmorehouse closed 9 years ago

jonmorehouse commented 9 years ago

Hello, I'm running into a really weird issue when testing KVO changes that are made in a background thread


class Test

  attr_accessor :test
  include BW::KVO

  def initialize
    self.test = :value_1
  end

  def background_change
    Dispatch::Queue.concurrent.async do
      self.test = :background
    end
  end

  def change
    self.test = :main
  end
end

describe "Multithreaded KVO" do

  it "background kvo" do

    obj = Test.new
    wait_for_change obj, 'test', 10.0 do
      "test".should.equal "test"
    end

    # NOTE running .change works fine ??
    obj.background_change
  end

  it "works okay" do

    wait_max 5.0 do
      "test".should.equal "test"
    end
    resume
  end

end

I get a spec timeout each time I run this kvo change in the background. If it changes in the correct thread, its fine. Has anyone else run into this issue?

https://gist.github.com/jonmorehouse/a5d2fc40a1321a0743fe

jonmorehouse commented 9 years ago

Digging a bit deeper into this issue and it seems like it should be somewhat expected behavior. Which makes me think this could be a good place for bubblewrap to help out :)

What do you think of changing the observe behavior, so that when a notification is generated it calls the observe blocks on the correct dispatch contexts? This would involve storing the queue internally, as well as changing up the KVO api internally (not sure how the blocks are triggered, I'll dig deeper into that in a bit)

clayallsopp commented 9 years ago

Hm so I'm not sure how wait_for_change works internally, but from objc.io:

Generally speaking, we cannot recommend mixing KVO and multithreading. If we are using multiple queues or threads, we should not be using KVO between queues or threads.

I'd be wary of dealing with that in BW.

jonmorehouse commented 9 years ago

Yeah, digging into it I think its a pretty big problem to fill. Especially if Apple doesn't recommend it.

I think this might have to turn into another gem, at some point :)