2016-12-25 6 views
0

나는 Gurdev가 제안한대로 완료 핸들러를 시도하고 뭔가를 얻었습니다. 그것은 MAIN 함수 내 배열의 값을 반환합니다. 그러나 문제는 동일합니다. HTTP 요청이 완료 될 때까지 3 초 동안 Sleep() 함수를 사용해야합니다. 이는 완료하는 데 3 초 미만 또는 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에 대한 모든 권리를 보유한 저작권 보호 콘텐츠를 사용할 수 없습니다. http://stackoverflow.com/help/licensing –

답변

2

을 코드에서 ar1에 값이 Aysnchronous 콜백 완료 핸들러에서 설정되는 반면에 당신이 당신의 메서드의 반환 문에서 ar1를 반환한다. ar1 값에 액세스하려고하는 완료 핸들러 블록을 사용해야합니다. HTTPGet 함수가 비동기 모드에서 실행 중이고 ar1의 값이 콜백 처리기 블록에 설정되어 있습니다.

추가 도움이 필요하면 알려주세요.

+1

return 문은 HTTP 요청이 서버로부터 응답을받는 동안 조기에 값을 반환합니다. 완료 핸들러 블록을 사용하도록'getData' 함수를 변경해야합니다. 완성 처리기 콜백 내에서'ar1'의 값을 사용하는 논리를 작성하도록'getData'를 호출하는 코드를 변경해야합니다. https://thatthinginswift.com/completion-handlers/ –