ios - Swift 中的 NSNotificationCenter 行为不正确(只调用函数中的某些东西)

标签 ios uitableview swift nsnotificationcenter

我正在使用 NSNotificationCenter 在通过 http 请求接收数据时触发 tableView.reloadData()。 99% 的时间,tableView 不会重新加载。只有在终止应用程序、删除、清理并再次运行后,它才会运行……但只是第一次。

MainVC.swift

import UIKit
class MainVC: UIViewController, UITableViewDelegate, UITableViewDataSource {

let needMetNotificationKey = "kNeedMetKey"
@IBOutlet var tableView: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "needMet", name: needMetNotificationKey, object: nil)
}

func needMet() {
    startConnectionAt(url)
    tableView.reloadData()
    println("executed")
}
func startConnectionAt(urlPath: String){
    var url: NSURL = NSURL(string: urlPath)
    var request: NSURLRequest = NSURLRequest(URL: url)
    var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)
    connection.start()
}

AcceptVC.swift

这是呈现我的表单并发出 http 请求的 VC,然后返回到 MainVC。

import UIKit
class AcceptVC: UIViewController, UITextFieldDelegate {

@IBOutlet var receiveName: UITextField!
@IBOutlet var receiveEmail: UITextField!
@IBOutlet var receivePhone: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()
@IBAction func signupForNeed() {

    var URL: NSURL = NSURL(string: "http://www.domain.com/json.php")
    var request: NSMutableURLRequest = NSMutableURLRequest(URL:URL)
    request.HTTPMethod = "POST"
    var needName = receiveName
    var needEmail = receiveEmail
    var needPhone = receivePhone

    var signup: String = "id=\(passedID)&name=\(needName.text)&email=\(needEmail.text)&phone=\(needPhone.text)"
    request.HTTPBody = signup.dataUsingEncoding(NSUTF8StringEncoding)

    NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {
        (response, data, error) in println(NSString(data: data, encoding: NSUTF8StringEncoding))
    }

    NSNotificationCenter.defaultCenter().postNotificationName(needMetNotificationKey, object: nil, userInfo: nil)

    navigationController?.presentingViewController?.dismissViewControllerAnimated(true, completion: {})
    }

我已将 println("executed") 添加到 needMet() 函数的末尾,以验证它确实到达了函数的末尾。可靠地,总是打印“已执行”。

当我在其他任何地方使用 startConnectionAt(url) 和 tableView.reloadData() 时,它会正常运行。为什么它在这里没有按应有的方式运行?

最佳答案

您是在请求发送后立即发布通知,而不是在请求完成后立即发布。您需要在 sendAsynchronousRequest 的完成闭包中移动 postNotificationName 调用:

NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {
    (response, data, error) in 

    println(NSString(data: data, encoding: NSUTF8StringEncoding))
    NSNotificationCenter.defaultCenter().postNotificationName(needMetNotificationKey, object: nil, userInfo: nil)
}

此外,您需要确保在主队列上完成所有 UI 工作,因此在您的 needMet 函数中,您应该使用 dispatch_async将工作分派(dispatch)到主队列:

func needMet() {
    startConnectionAt(url)

    dispatch_async(dispatch_get_main_queue()) {
        tableView.reloadData()
        println("executed")
    }
}

注意:我建议阅读 Concurrency Programming了解 dispatch_async、为什么需要使用它以及一些替代方案。

您似乎还在 viewDidLoad 中定义了 signupForNeed。这实际上应该是类本身的一个函数,而不是嵌套函数。

关于ios - Swift 中的 NSNotificationCenter 行为不正确(只调用函数中的某些东西),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26043576/

相关文章:

ios - iBeacon 监控具有相同 UUID 和不同主要、次要的多个信标

objective-c - 在 UITableView 中自定义索​​引/部分栏的字体/背景颜色

iOS - 表格 View 单元格无法正确呈现

swift - 如何从网站获取图像源 - Swift & Kanna

ios - dataSource 不会在 cellForItemAt 函数中更新

ios - Swift Charts 创建多标签标记

ios - 特定应用内购买的年龄限制更高?

ios - 当我尝试构建我的项目时出现以下错误

ios - 自动布局可以调整 UITableView 的大小以在 ipad 上纵向增长和横向缩小吗?

ios - Apple Mach-O-Linker 错误 CocoaPods