2016-04-21 2 views
0

У меня есть часть кода, в которой опционально инициализируется, а затем присваивается значение в функции, но nill при распаковке?Быстрые переменные значения и функции

var datastring: String? 
Alamofire.request(.POST, "https://example.url/request", parameters: parameters) .response { request, response, data, error in 
    datastring = NSString(data: data!, encoding:NSUTF8StringEncoding) as! String // there is data in here 
    // textView.text = datastring! datastring is not nill when here 
}  
textView.text = datastring! // datastring is nill when here 

Это не Амалофир. Я столкнулся с этой проблемой при использовании собственных методов Swift. Что я делаю неправильно, и почему это работает?

PS. Я все еще учусь :)

EDIT: Спасибо всем, кто мне помог. Чтобы прояснить проблему, речь шла о передаче значения переменной из асинхронного потока в основной поток. Я просто не знал, как это сказать.

+3

Datastring устанавливается внутри обратного вызова (асинхронно). Тем временем основной поток продолжает работать, поэтому ваша переменная не имеет в нем ничего, когда установлен textView.text. Вам нужно передать свое значение обратно в основной поток в другой обратный вызов. – ohiodoug

+0

Возможный дубликат [Alamofire request coming nil] (http://stackoverflow.com/questions/35372850/alamofire-request-coming-up-nil) – jtbandes

+0

@ohiodoug Спасибо, что объяснили это. Это то, чего я не понял. –

ответ

3

Вы обновляете переменную datastring в закрытии. Это код, который передается Alamofire для выполнения позже (возможно, через микросекунды). Таким образом, строка, назначая datastring на textView, происходит сначала, прежде чем закрытие будет выполнено.

Попробуйте вместо этого:

var datastring: String? 

Alamofire.request(.POST, "https://example.url/request", parameters: parameters).response { request, response, data, error in 
    datastring = NSString(data: data!, encoding: NSUTF8StringEncoding) as! String 

    dispatch_async(dispatch_get_main_queue()) { 
     textView.text = datastring 
    } 
} 

Использование dispatch_async вызова обеспечивает обновление пользовательского интерфейса происходит в основном потоке.

Возможно, что сетевой запрос не будет выполняться в течение нескольких секунд (или дольше), поэтому вы можете обновить интерфейс с временной строкой, чтобы пользователь мог что-то увидеть во время ожидания.

+0

Спасибо, что объяснили это. Ваши объяснения и @ ohiodoug мне очень помогли. Отметьте этот ответ, потому что dispatch_async, что мне нужно, чтобы вернуться к основному потоку. –

+0

Удивительный, рад помочь. Кроме того, поскольку вы новичок в Swift, старайтесь избегать использования '!' Как можно больше. Вы должны рассматривать каждое использование '!' В качестве возможной точки крушения. Моя команда на самом деле называет их «сбоями». –

+0

@DaveWood, 'crash bangs' - Мне это нравится. (О, и привет.) – NRitH

0

Эти две линии

datastring = NSString(data: data!, encoding:NSUTF8StringEncoding) as! String // there is data in here 
textView.text = datastring! // datastring is not nill when here 

являются не запускается сразу, так как они находятся внутри крышки. Это зависит от Аламофира, чтобы решить, когда запустить закрытие.

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