【问题标题】:Async issue on getting values from the server从服务器获取值的异步问题
【发布时间】:2016-07-02 01:14:09
【问题描述】:

在我的viewDidLoad 我愿意:

// Get Profile Info
    NSOperationQueue.mainQueue().addOperationWithBlock { () -> Void in
        let getMyProfileURL = "\(self.property.host)\(self.property.getMyProfile)"
        print(getMyProfileURL)
        Alamofire.request(.POST, getMyProfileURL, parameters: self.property.profileParameteres, encoding: .JSON).responseJSON { response in
            do {
                let json = JSON(data: response.data!)

                if json["user"].count > 0 {
                    self.profileDetails.append(ProfileDetailsModel(json: json["user"]))
                }
            }
        }

        print(self.profileDetails[0].firstName)
    }

所以,当我想从数组中获取firstName 时:

 print(self.profileDetails[0].firstName)

我的应用程序因错误而崩溃:

fatal error: Array index out of range

我的数组是空的。我已经使用了NSOperationQueue,但我仍然得到空数组并崩溃。如何解决此问题并从控制器中的任何位置访问我的 filled 数组,而不仅仅是在 Alamofire 块内?

【问题讨论】:

  • 如果数组为空,可能意味着您没有从服务器获得任何响应。或者您访问 json 的密钥错误。
  • 另外,您的 json 本身可能会作为数组返回,因此请尝试使用 json[0]["user"] 之类的方法来访问第一个等。
  • 试试print(json) 看看你正在使用什么样的数据结构。
  • @Phoen1xUK 我知道我有什么数据。那不是我的问题。我的问题是从我的控制器中的其他地方访问它
  • 啊,是的,在重新阅读您的代码并查看其他答案之后,我可以看到您正在尝试在请求完成之前访问数组,因为 Alamofire 请求将是异步的,并且打印将立即执行。

标签: ios swift asynchronous alamofire nsoperationqueue


【解决方案1】:

我建议重构您的代码,将其移至viewDidLoad 之外的函数中,然后添加您自己的完成处理程序。比如:

func getData(completion: () -> Void) {
    NSOperationQueue.mainQueue().addOperationWithBlock { () -> Void in
        let getMyProfileURL = "\(self.property.host)\(self.property.getMyProfile)"
        print(getMyProfileURL)
        Alamofire.request(.POST, getMyProfileURL, parameters: self.property.profileParameteres, encoding: .JSON).responseJSON { response in
            do {
                let json = JSON(data: response.data!)

                if json["user"].count > 0 {
                    self.profileDetails.append(ProfileDetailsModel(json: json["user"]))
                }
            }
            completion()
        }
    }
}

然后在 viewDidLoad 中,您可以使用其完成处理程序调用它,以在完成后访问 Alamofire 块之外的数据,例如

getData() {
    print(self.profileDetails[0].firstName)
}

【讨论】:

  • 我的 collectionView 单元格计数有问题。当我试图从我的self.profileDetails.first?.myArrayThere.count 设置它的值时,我得到nil。我该如何解决?
【解决方案2】:

请求是异步的,它只会在收到应答时填充self.profileDetails数组,并执行completionHandler块。

在您的代码中,您调用执行异步任务,它将在另一个线程中运行,并且应用程序返回下一个操作并立即尝试访问self.profileDetails,当时可能仍然是@987654324 @。

您必须等待完成处理程序块完成以填充数组,然后访问数据。

@Md.Muzahidul Islam 的代码将按您的意愿工作。

【讨论】:

  • 但我也想从其他地方实现它。我不想只从 Alamofire 块访问它
  • @JohnDoe,完成后,数组中的数据将始终可用。你可以有一个标志来检查数据是否被加载,或者调用其他函数来通知任务结束
  • 我的 collectionView 单元格计数有问题。当我试图从我的self.profileDetails.first?.myArrayThere.count 中设置它的值时,我得到了 nil。我该如何解决?
  • 你能提供更多细节吗?我不明白这个问题。
【解决方案3】:

现在可以正常使用了

  NSOperationQueue.mainQueue().addOperationWithBlock { () -> Void in
        let getMyProfileURL = "\(self.property.host)\(self.property.getMyProfile)"
        print(getMyProfileURL)
        Alamofire.request(.POST, getMyProfileURL, parameters: self.property.profileParameteres, encoding: .JSON).responseJSON { response in
            do {
                let json = JSON(data: response.data!)

                if json["user"].count > 0 {
                    self.profileDetails.append(ProfileDetailsModel(json: json["user"]))
                }
            }
        print(self.profileDetails[0].firstName)
        }

    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    • 2020-11-06
    • 1970-01-01
    • 2014-10-28
    • 2014-03-02
    • 2018-03-02
    相关资源
    最近更新 更多