2016-04-08 3 views
0

「遅い」とは、リモートサーバがタイムアウトするのを待つコールバックの種類(vimeoフィードを呼び出し、解析してシーンにuiviewsを表示する)iOS9 // NSURLSession dataTaskWithURL非常に「遅い」

ほとんどどのように動作するのですか?私は、私の見解は、すぐに応答が以下のコード持っ

を返されるとコールバック内から移入されたいのですが(rubymotionを、あなたのアイデアを得る可能性があります):

session = NSURLSession.sharedSession 
url = NSURL.URLWithString(ALBUMS_URL) 
downloadTask = session.dataTaskWithURL(url, completionHandler: lambda { |data, response, error| 
    # 'puts' prints the result in the console, you get it as soon as the response arrives 
    puts data 
    # testing with a simple view 
    v = UIView.alloc.initWithFrame(CGRectMake(0,0,@width/2,200)) 
    v.backgroundColor = UIColor.blackColor 
    self.view.addSubview v # ==> takes forever to effectively appear on the scene 
}) 

私が設定してしまいました他の次

NSURLSession.sessionWithConfiguration(
    NSURLSessionConfiguration.defaultSessionConfiguration, 
    delegate:nil, 
    delegateQueue: NSOperationQueue.mainQueue 
) 

何かをメインスレッドでタスクのこの種を行うために使用すべきですか?ビューを更新して強制的に更新する方法はありますか?この1

+1

だこと:あなたは()(申し訳ありませんが、私はRubyMotionに慣れていないので、私はObjective-Cでこれを書いている)このように、UIを更新ブロックを作るために呼び出す簡単なdispatch_asyncを行うことができますあなたの質問に答えるのに十分な情報がありません。 – trojanfoe

+0

@trojanfoeもっと正確にする方法を教えてください。基本的に、それをメインスレッドに入れずに、更新するには30秒かかります – Ben

+0

@trojanfoeが編集しました – Ben

答えて

1

UIの更新に時間がかかりすぎる理由は、操作に時間がかかったためではありませんが、NSURLSessionDataTaskがバックグラウンドスレッドで終了するためです。ご存じのように、バックグラウンドのスレッド(メインスレッドのみ)からUIの変更を行うことは想定されていません。

URLセッションのコールバック全体をメインキューに入れるソリューションは、メインキューでネットワーク操作を行っているため、この問題を "解決"しますが、正しい方法ではありません。 (ネットワーク操作のように)バックグラウンドで行うことができます。

これを修正するには、バックグラウンドスレッドでネットワーク操作を行い、最後にメインスレッドでUI変更ロジックを呼び出します。

// in the callback for NSURLSessionDataTask: 
NSLog(@"%@", data); 

// Dispatch the UI-related logic as a block on the main-thread 
dispatch_async(dispatch_get_main_queue(), ^{ 
    UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0,0,width/2,200)]; 
    v.backgroundColor = [UIColor blackColor]; 
    [self.view addSubview:v]; 
}); 
1

上のあなたの助けのための

おかげで、それは完全に到着するデータのための30秒かかりますように聞こえます。データをより速く表示するには、デリゲートを使用し、受け取ったデータを一度にチャンクとして取得し、部分的に受信したデータを処理する方法を知っているパーサーを使用してから、UIにデータを追加する必要があります。追加のデータを受け取ります。

編集:何とかこれまで私がこれに答えたとき、私はメインスレッドで動かないときにしか失敗しなかったという事実を忘れてしまった。他のコメント欄に記されているように、である必要があります。メインスレッドでタスクを開始するか、ブロック内でdispatch_asyncを使用して、ラベル変更をメインスレッドで実行します。そうしないと、メインスレッド上で実行中の他のコードが問題のビューの再描画を引き起こすまで、UIは更新されません。