Swift中的NSNotificationCenter无法正常运行(仅调用函数中的某些内容)

时间:2014-09-25 16:27:09

标签: 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

这是VC,它呈现我的表单并发出http请求,然后返回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()时,它的行为应该如此。为什么它不能在这里运作呢?

1 个答案:

答案 0 :(得分:1)

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

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将工作分派到主队列:< / p>

func needMet() {
    startConnectionAt(url)

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

注意:我建议您阅读Concurrency Programming,了解dispatch_async,为什么需要使用它,以及其他一些选择。

您似乎也在signupForNeed内定义了viewDidLoad。这应该是类本身的一个函数,而不是嵌套函数。