2016-12-25 17 views
0

私はGurdevが提案したように補完ハンドラを試して何かを得ました。私の配列の値をMAIN関数に返します。しかし、問題は同じです:私はスリープ()関数を3秒間、HTTP要求が完了するために使用する必要があります。これは、ハードコーディングのように、完了までに3秒以上かかることがあります。 Sleep()コマンドを削除すると、VOID配列が返されます。与えられた関数の外の変数へのアクセス

関連コードは以下のとおりです。

ありがとうございます!基本的に

--------Web Class-------- 
    import Foundation 
    import UIKit 

    class Web { 

     var ar1 = [Double]() 

     var ar2 = [Double]() 

     func getData(str: String, completion: (_ result: [[Double]]) -> Void) { 

    let request = NSMutableURLRequest(url: URL(string: str)!) 

    httpGet(request as URLRequest!){ 
     (data, error) -> Void in 
     if error != nil { 
      print(error ?? "Error") 
     } else { 
      let delimiter = "\t" 
      let lines:[String] = data.components(separatedBy: CharacterSet.newlines) as [String] 

     for line in lines { 
       var values:[String] = [] 
       if line != "" { 
        values = line.components(separatedBy: delimiter) 
        let str1 = (values[0])//FIRST COLUMN 
        let str2 = (values[1])//SECOND COLUMN 
        let db1 = NumberFormatter().number(from: str1)?.doubleValue 
        self.ar1.append(db1!) 
        let db2 = NumberFormatter().number(from: str2)?.doubleValue 
        self.ar2.append(db2!) 

       } 

      } 

     } 

    }//end of request 

    sleep(3) // This delay sends data to MAIN, Otherwise NOT 

    let dta = [self.ar1, self.ar2] 

    completion(dta) 

    } 

    func httpGet(_ request: URLRequest!, callback: @escaping (String, String?) -> Void) { 
    let session = URLSession.shared 
    let task = session.dataTask(with: request, completionHandler: { 
     (data, response, error) -> Void in 
     if error != nil { 
      callback("", error!.localizedDescription) 
     } else { 
      let result = NSString(data: data!, encoding: 
       String.Encoding.ascii.rawValue)! 
      callback(result as String, nil) 
     } 
     }) 
     task.resume() 
    } 

} --------ウェブクラス--------

-------Call In Class-------- 
Web().getData (str: "https://dl.dropboxusercontent.com/s/f6j7w7zeqaavzqw/s02.txt?dl=0") 
     { 
     (result: [[Double]]) in 

      let x = result[0] 
      let y = result[1] 
} 
-------Call In Class-------- 

、私は、ある時点で私の変数 "AR1" にアクセスしようとしています私のコードではできません。私も値を返そうとしていますが、その時点でNULLを返します。

ここで何が間違っていますか?

私は以下のコードのように試してみました:あなたのコードで

import Foundation 
import UIKit 

class Web { 
    var ar1 = [Double]() 
    var ar2 = [Double]() 

    func getData(str: String) -> [Double] { 
    let request = NSMutableURLRequest(url: URL(string: str)!) 
     httpGet(request as URLRequest!){ 
      (data, error) -> Void in 
      if error != nil { 
       print(error ?? "Error") 
      } else { 
       let delimiter = "\t" 
       let lines:[String] = data.components(separatedBy:  CharacterSet.newlines) as [String] 

       for line in lines {   
        var values:[String] = [] 
        if line != "" { 
         values = line.components(separatedBy: delimiter) 
         let str1 = (values[0])//FIRST COLUMN 
         let str2 = (values[1])//SECOND COLUMN 
         let db1 = NumberFormatter().number(from: str1)?.doubleValue 
         self.ar1.append(db1!) 
         let db2 = NumberFormatter().number(from: str2)?.doubleValue 
         self.ar2.append(db2!) 
        } 
       } 
      dump (self.ar1) // "ar1" accessible HERE (returns all elements) 
     } 
    }//end of request 
     //BUT I WANT TO RETURN "ar1" HERE ! 
     // So that I can use it in my MAIN class 
     dump (self.ar1) // "ar1" not accessible here (returns ZERO elements) 
     return self.ar1 
    } 
     func httpGet(_ request: URLRequest!, callback: @escaping (String, String?) -> Void) { 
      let session = URLSession.shared 
      let task = session.dataTask(with: request, completionHandler: { 
       (data, response, error) -> Void in 
       if error != nil { 
       callback("", error!.localizedDescription) 
       } else { 
       let result = NSString(data: data!, encoding: 
        String.Encoding.ascii.rawValue)! 
       callback(result as String, nil) 
       } 
      }) 
      task.resume() 
} 
    } 
+0

おそらく、StackOverflowで予約されているすべての著作権で保護されたコンテンツを使用することはできません。 –

答えて

2

ar1に値がAysnchronousコールバック完了ハンドラに設定されているのに対し、あなたのメソッドのreturn文からar1を戻ってきています。 ar1の値にアクセスしようとしている完了ハンドラブロックを使用する必要があります。 HTTPGet関数が非同期モードで実行されており、ar1の値がコールバックハンドラブロックで設定されています。

これについて詳しいヘルプが必要な場合はお知らせください。

+1

returnステートメントは、HTTP要求がまだサーバーからの応答を受信して​​いる間に早期に値を返します。詳細については、http://stackoverflow.com/help/licensingを参照してください。補完ハンドラブロックを使用するように、関数 'getData'を変更する必要があります。補完ハンドラのコールバック内で 'ar1'の値を使うロジックを書くために、現在' getData'を呼び出すコードを変更する必要もあります。 https://thatthinginswift.com/completion-handlers/ –

関連する問題