问题
I am new to RubyMotion and trying to understand how object initialization works. Suppose a simple class with one class and one instance method:
class Something
def self.getSomething
BubbleWrap::HTTP.post("http://example.com") do |response|
p response
end
end
def getSomething
BubbleWrap::HTTP.post("http://example.com") do |response|
p response
end
end
end
Now, why does the following work:
Something.getSomething
And the next snippet not, well, sometimes (ran this snippet and the runtime crashed 8 out of 10 times).
something = Something.new
something.getSomething
I am doing it wrong. Any pointers in the right direction?
回答1:
Use instance variables:
@something = Something.new
@something.getSomething
RubyMotion has a handful of bugs related to local variables and blocks. You're assigning to something
and then calling something.getSomething
, which then uses BubbleWrap's asynchronous HTTP.post
method. The BubbleWrap HTTP block runs, but in the meantime, the method you're calling something.getSomething
from has completed execution. Since something
is a local variable, it gets garbage collected when the method exits. So when the HTTP request completes and the block is called, the block no longer exists.
You're probably seeing random inconsistent errors (and once in a while an actual working request) because each time, the memory location where the block was stored was reclaimed for something else (or once in a while, it wasn't reclaimed at all so the block is still there). None of this happens when you use an instance variable instead, because when the calling method finishes execution, the instance variable sticks around.
This behavior is definitely unexpected; I know a couple issues have been filed (myself included) to get this fixed.
来源:https://stackoverflow.com/questions/13159990/object-initialization-in-rubymotion