如何从Swift闭包中返回值?

时间:2022-04-16 14:02:05

I'm new at swift closures. I have this code and i can't extract the values from the forloop into the arrays outside the closure.

我是快速关闭的新手。我有这个代码,我无法将forloop中的值提取到闭包外的数组中。

Sorry about this question but i have already searched stackflow but without success in this specific case.

对这个问题很抱歉,但我已经搜索了stackflow但在这个特定情况下没有成功。

Thanks in advance.

提前致谢。

var namesArray: [String] = []
var imagesArray: [String] = []
var timesArray: [String] = []
var placesArray: [String] = []

func getData(){
    //DATA SOURCE
    // Create request for user's Facebook data
    let request = FBSDKGraphRequest(graphPath: cmp.pageId, parameters: ["fields": "events"])

    // Send request to Facebook
    request.startWithCompletionHandler {

        (connection, result, error) in

        if error != nil {
            // Some error checking here
            print(error.debugDescription)
        } else
            if let pageData = result["events"] {
                print(result["events"]!!["data"]!![0]["name"])
                if let eventDetails = pageData!["data"] {

                    // EVENT DETAILS FETCH
                    for var i = 0; i < eventDetails!.count; i++
                    {
                        let fetchedEventName = eventDetails![i]["name"] as? String!
                        let fetchedEventTime = eventDetails![i]["start_time"] as? String!

                        if eventDetails?[i]["place"]??["name"] != nil {
                            if let fetchedEventPlace = eventDetails?[i]["place"]??["name"] {
                                self.placesArray.append(fetchedEventPlace! as! String)
                            }
                        } else {
                            self.placesArray.append("Lisbon")
                        }
                        self.namesArray.append(fetchedEventName!)
                        self.timesArray.append(fetchedEventTime!)
                    }
                    print("Name of event: \(self.namesArray)")
                }
            } else {
                print("Error.")
        }
    }
}

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.delegate = self
    tableView.dataSource = self

    getData()
}

EDIT: I want to show the fetched result into a tableview that's already set. Heres the tableview code.

编辑:我想将获取的结果显示到已经设置的tableview中。下面是tableview代码。

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    if let cell = tableView.dequeueReusableCellWithIdentifier("previewCell") as? PreviewCell {

        var img: UIImage!

        let url = NSURL(string: imagesArray[indexPath.row])!
        if let data = NSData(contentsOfURL: url){
            img = UIImage(data: data)
        } else {
            img = UIImage(named: "ant")
        }

        cell.configureCell(img, title: namesArray[indexPath.row], time: timesArray[indexPath.row], place: placesArray[indexPath.row])

        return cell
    } else {
        return PreviewCell()
    }
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return namesArray.count
}

func addNewEvent(name: String, image: String, time: String, place: String)
{
    namesArray.append(name)
    imagesArray.append(image)
    timesArray.append(time)
    placesArray.append(place)
}

2 个解决方案

#1


1  

You are already getting the number in to the arrays so what you need to do is just reload the tableview after the for loop.

您已经将数字输入到数组中,因此您需要做的只是在for循环后重新加载tableview。

//end of for-loop
self.tableView.reloadData()

The reason for this is the asynchronous execution of the request.startWithCompletionHandler. The code inside that block will most likely execute after your tableView already loaded and it therefor needs a reload after the data has been fetched

原因是request.startWithCompletionHandler的异步执行。该块中的代码很可能在tableView已经加载后执行,因此在获取数据后需要重新加载

#2


0  

In case if you need to return data from closure you can define completion on your getData() method like this

如果您需要从闭包返回数据,您可以像这样定义getData()方法的完成

func getData(completion:([DataType]) -> Void) {
    //process data
    let dataArray:DataType = []
    completion(dataArray)
}

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.delegate = self
    tableView.dataSource = self

    getData { (completionData) -> Void in
        // process returned data 
    }
}

Hope this helps

希望这可以帮助

#1


1  

You are already getting the number in to the arrays so what you need to do is just reload the tableview after the for loop.

您已经将数字输入到数组中,因此您需要做的只是在for循环后重新加载tableview。

//end of for-loop
self.tableView.reloadData()

The reason for this is the asynchronous execution of the request.startWithCompletionHandler. The code inside that block will most likely execute after your tableView already loaded and it therefor needs a reload after the data has been fetched

原因是request.startWithCompletionHandler的异步执行。该块中的代码很可能在tableView已经加载后执行,因此在获取数据后需要重新加载

#2


0  

In case if you need to return data from closure you can define completion on your getData() method like this

如果您需要从闭包返回数据,您可以像这样定义getData()方法的完成

func getData(completion:([DataType]) -> Void) {
    //process data
    let dataArray:DataType = []
    completion(dataArray)
}

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.delegate = self
    tableView.dataSource = self

    getData { (completionData) -> Void in
        // process returned data 
    }
}

Hope this helps

希望这可以帮助