【问题标题】:Accessing a variable outside a given function访问给定函数之外的变量
【发布时间】:2016-12-25 09:15:02
【问题描述】:

我按照 Gurdev 的建议尝试了完成处理程序并得到了一些东西。它确实在 MAIN 函数中返回我的数组的值。但问题是一样的:我必须使用 Sleep() 函数 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()
}
    }

【问题讨论】:

标签: swift variables completion


【解决方案1】:

在您的代码中,您从方法的 return 语句返回 ar1,而 ar1 的值是在 Aysnchronous 回调完成处理程序中设置的。您应该在尝试访问ar1 值的地方使用完成处理程序块。 HTTPGet 函数在异步模式下运行,ar1 中的值在回调处理程序块中设置。

如果您需要任何进一步的帮助,请告诉我。

【讨论】:

  • 您的 return 语句提前返回值,而 HTTP 请求仍在接收来自服务器的响应。您需要更改函数 getData 以便它使用完成处理程序块。您还需要更改当前调用getData 的代码,以便编写在完成处理程序回调中使用ar1 值的逻辑。 thatthinginswift.com/completion-handlers
猜你喜欢
  • 2017-09-11
  • 1970-01-01
  • 1970-01-01
  • 2014-04-09
  • 2014-07-11
  • 1970-01-01
  • 2019-09-15
  • 1970-01-01
  • 2021-05-28
相关资源
最近更新 更多