Rubymotion Dispatch завершает работу раньше времени

Я выполняю довольно ванильную очередь отправки в Rubymotion, однако она, по-видимому, завершается раньше. Он никогда не проходит мимо вызова initWithContentsOfURL. Однако удаление оболочки Dispatch::Queue и размещение вызовов в основном потоке работает.

Приложение в симуляторе завершает работу без трассировки стека или указаний на то, что пошло не так. Я неправильно использую очередь отправки?

def foo
  Dispatch::Queue.concurrent.async do
    error_ptr = Pointer.new(:object)
    data = NSData.alloc.initWithContentsOfURL(
      NSURL.URLWithString(url), options:NSDataReadingUncached, error:error_ptr)
    unless data
      p error_ptr[0]
      return
    end
    json = NSJSONSerialization.JSONObjectWithData(data, options:0, error:error_ptr)
    unless json
      presentError error_ptr[0]
      return
    end
    Dispatch::Queue.main.sync { print_results(json) }
  end
end

def print_results(json)
  p "#{json}"
end

person nathasm    schedule 30.05.2012    source источник
comment
Ваш код показывает, что метод print_results встроен в ваш вызов Dispatch -- действительно ли он настроен таким образом или вызов Dispatch содержится в другом методе?   -  person Dylan Markow    schedule 30.05.2012
comment
Это не встроено. Это отдельный звонок. Отправка должна быть заключена в метод.   -  person nathasm    schedule 31.05.2012
comment
Ну, тогда ваш код отлично работает для меня на RubyMotion 1.8; может быть, это проблема с конкретным URL-адресом, который вы пытаетесь загрузить?   -  person Dylan Markow    schedule 31.05.2012
comment
Спасибо, Дилан. Вы поставили меня на правильный путь. Если я установлю что-то вроде url = "http://www.google.com", это не удастся. Но если я помещу строку непосредственно в вызов URLWithString, это сработает.   -  person nathasm    schedule 01.06.2012
comment
Странный. Где вы устанавливали url? В методе foo или где-то еще в вашем коде?   -  person Dylan Markow    schedule 01.06.2012
comment
После def foo, но до Dispatch.   -  person nathasm    schedule 01.06.2012


Ответы (3)


Прямо сейчас кажется, что RubyMotion неправильно сохраняет локальные переменные вне блока диспетчеризации, поэтому, вероятно, получает EXEC_BAD_ACCESS и сбой. Не удается выполнить следующее:

foo = "some value"
Dispatch::Queue.concurrent.async do
    puts foo
end

Однако следующие два будут работать:

@foo = "some value"
Dispatch::Queue.concurrent.async do
    puts @foo
end

а также:

foo = "some value"
foo.retain
Dispatch::Queue.concurrent.async do
    puts foo
    foo.release
end
person Mason Cloud    schedule 13.06.2012

Я думаю, что отследил проблему. Это было потому, что я объявлял URL в методе

def foo
url = "www.google.com"
  Dispatch
    take action on url
  end
end

Переместив объявление URL-адреса в поток Dispatch, он работает. Я думаю, что это было связано с тем, что локальная переменная метода вышла за пределы области видимости до того, как задача успела выполниться.

def foo
  Dispatch
    url = "www.google.com"
    take action on url
  end
end
person nathasm    schedule 01.06.2012

В моем случае объявление url в методе в RubyMotion 2.5 было нормальным, но мое приложение вылетало с EXC_BAD_ACCESS, а иногда и с другими сообщениями об ошибках из-за символов юникода в имени приложения и во всем моем коде. Исправление заголовка кодировки и изменение имени приложения решили мою проблему. Удивительно, но приложение работало нормально и вылетало только тогда, когда я звонил initWithContentsOfURL.

person Andrei    schedule 05.08.2013