2016-01-12 2 views
-2

У меня есть этот код:Возвращаемое значение из асинхронного метода SQL

- (NSString *)obtenerDatosUsuario 
{ 
    __block NSString *[email protected]""; 
    [self obtenerDatosUsuarioSQL:^(NSString *resultadoSQL){ 
     result=resultadoSQL; 
    }]; 
    return result; 
} 

И я хочу, что возвращение будет содержание resultadoSQL

+2

Выполняет ли '-obtenerDatosUsuarioSQL:' синхронно или асинхронно? Во втором случае ваш оператор 'return' будет выполняться до того, как будет выполнен блок, и, следовательно,' result' еще не будет установлен. –

+0

(Похоже, что он асинхронен: иначе он просто вернет 'NSString' вместо принятия блока в качестве аргумента.) –

+0

Что этот код имеет отношение к быстрому? – Sulthan

ответ

0

Если мое предположение верно о том, что происходит внутри вашего метода -obtenerDatosUsuarioSQL: (т.е. , он выполняет длительную операцию в фоновом потоке и дает результат аргументу переданного блока), то ваш код работает в следующем порядке:

  1. Вы звоните -obtenerDatosUsuario
  2. -obtenerDatosUsuarioSQL:, передача завершение обработчик блок.
  3. Выполнение выполняется вперед и достигает инструкции return в конце -obtenerDatosUsuario и выходит из тела метода. Возвращаемая переменная result еще не установлен!
  4. Спустя некоторое время SQL-запрос завершается и выполняется блок. Но вернуть результат слишком поздно, потому что выполнение уже завершило метод -obtenerDatosUsuario.
+0

Существует один способ вернуть содержимое переменной, называемой resultadoSQL в обратном? – Ruben

0

Есть способы сделать синхронно этот асинхронный метод (например, семафоры), но это, как правило, очень и очень плохая идея. Скорее всего, obtenerDatosUsuarioSQL является асинхронным, потому что есть шанс (пусть даже небольшой шанс), что результат не будет возвращен немедленно. Возможно, возможно, что SQL будет медленным. Или, может быть, вы в конечном итоге будете делать запросы из нескольких потоков, поэтому этому запросу может потребоваться дождаться запросов в других потоках. Или могут быть другие причины. Но какова бы ни была причина, этот метод был реализован как асинхронный метод, и вы должны принять это, а не бороться с ним. Если вы измените obtenerDatosUsuario, чтобы вернуться синхронно, вы откроете себе множество разнообразных проблем.

Вместо этого вы должны просто принять асинхронный шаблон в своем коде. Например, давайте представим, что у вас есть код, который планирует использовать результат obtenerDatosUsuario для других целей, например:

NSString *resultadoSQL = [self obtenerDatosUsuario]; 
// use `resultadoSQL` here 

Просто изменить, что:

[self obtenerDatosUsuarioSQL:^(NSString *resultadoSQL){ 
    // use `resultadoSQL` here 
}]; 
// but not here 

И, если вы» повторно используя obtenerDatosUsuarioSQL в некотором методе, который вы сейчас пытаетесь вернуть значение немедленно, а затем измените его так же, как и асинхронно. Например, давайте предположим, что у вас было что-то вроде:

- (NSString *)someOtherMethod { 
    NSString *resultadoSQL = [self obtenerDatosUsuario]; 

    // let's assume you're doing something else with `resultadoSQL` to build some other string 

    NSString *string = ... // some expression using `resultadoSQL` 
    return string; 
} 

Тогда, вы бы изменить, что также принять асинхронной модели:

- (void)someOtherMethod:(void (^)(NSString *))completionHandler { 
    [self obtenerDatosUsuarioSQL:^(NSString *resultadoSQL){ 
     NSString *string = ... // some expression using `resultadoSQL` 
     completionHandler(resultadoSQL); 
    }]; 
} 

Когда вы впервые столкнулись это, это может показаться излишне сложным, но асинхронное программирование настолько критично, что является фундаментальной частью программирования Cocoa, что действительно нужно получить некоторое знакомство с этими общими асинхронными шаблонами, такими как блоки. Лично мы используем блок-синтаксис настолько, что I create code snippets в «Библиотеке фрагментов кода» Xcode для typical block patterns, что значительно упрощает жизнь и избавляет вас от мира запоминания неинтуитивного синтаксиса блока.

Но не испытывайте соблазн обернуть асинхронный метод другим способом, который заставляет его вести себя синхронно. Если вы это сделаете, вы откроете себе множество проблем.

Смежные вопросы