简体   繁体   English

使用performSegueWithIdentifier Swift 2.1时出错

[英]Error using performSegueWithIdentifier Swift 2.1

I'm trying to make a Segue programmatically using "performSegueWithIdentifier" but for some reason it's not working. 我正在尝试使用“performSegueWithIdentifier”以编程方式进行Segue,但由于某种原因它无法正常工作。 I'm going to post my code because it's really simple but it's showing a weird error. 我要发布我的代码,因为它非常简单,但它显示了一个奇怪的错误。

Here you are my code: 这是你的代码:

import UIKit

class LoginViewController: UIViewController {

@IBOutlet weak var login: UIButton!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func loginButtonPressed(sender: UIButton) {

    if (((user.text) != "") && ((password.text) != ""))
    {
        let request = NSMutableURLRequest(URL: NSURL(string: "http://website.com/login.php")!)
        request.HTTPMethod = "POST"
        let postString = "user="+user.text!+"&password="+password.text!

        request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
            data, response, error in

            if error != nil
            {
                print(error)
                return
            }

            let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)!

            if (responseString=="Correct")
            {
                self.performSegueWithIdentifier("loginSegue", sender: sender)
            }
            else
            {

            }

        }
        task.resume()
    }
    else
    {

    }
}

I have already created a Segue from my LoginViewController to a NavigationController with the ID "loginSegue", but it still not working. 我已经从我的LoginViewController创建了一个Segue到一个ID为“loginSegue”的NavigationController ,但它仍然无效。

What's wrong in my code? 我的代码有什么问题?

That's the error from Xcode: 这是Xcode的错误:

2015-11-23 21:09:43.224 App[5511:3896125] *** Assertion failure in -       [UIKeyboardTaskQueue waitUntilAllTasksAreFinished], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3512.29.5/Keyboard/UIKeyboardTaskQueue.m:378
2015-11-23 21:09:43.226 App[5511:3896125] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] may only be called from the main thread.'
*** First throw call stack:
(0x2232985b 0x33c9edff 0x22329731 0x230baddb 0x2648a5fd 0x2648aeaf 0x2648483b 0x26aa2321 0x265f2b23 0x267c44e7 0x267c5e55 0x267c81e5 0x267c8451 0x26556367 0x267cb6e7 0x267cb735 0x267dfb99 0x267cb65b 0x26a6e6b9 0x26b45919 0x26b45747 0x267bd87d 0x72fd0 0x71b0c 0x6e560 0x21b505b5 0x21b5fcd7 0x230e856d 0x23049fdf 0x2303c3cf 0x230ea82d 0x11e461b 0x11dcf53 0x11e5b0f 0x11e5961 0x34558e0d 0x345589fc)
libc++abi.dylib: terminating with uncaught exception of type NSException

NSURLSession's completion blocks are called on the sessions's delegate queue, which is run on a background thread unless you specify otherwise. NSURLSession的完成块在会话的委托队列上调用,该队列在后台线程上运行,除非您另行指定。

You should not call any UI code (pretty much the entire UIKit) from a background thread. 您不应该从后台线程调用任何UI代码(几乎是整个UIKit)。 Sometimes it works, sometimes it doesn't do anything, and sometimes it crashes. 有时候它可以工作,有时它什么都不做,有时会崩溃。 Don't do it. 不要这样做。

Thus you can't do ANY UI code in those completion blocks unless you send that code to the main thread, as Dan says in his answer. 因此,除非您将该代码发送到主线程,否则您无法在这些完成块中执行任何 UI代码,正如丹在他的回答中所说的那样。

The changed code might look like this: 更改后的代码可能如下所示:

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        data, response, error in
        if error != nil
        {
            print(error)
            return
        }
        let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)!

        if (responseString=="Correct")
        {
            //Use dispatch_async to do the performSegueWithIdentifier
            //on the main thread.
            dispatch_async(dispatch_get_main_queue())
            {
              self.performSegueWithIdentifier("loginSegue", sender: sender)
            }
        }
        else
        {
        }
    }

The most "simple" fix for this would probably be to just wrap the call to self.performSegueWithIdentifier("loginSegue", sender: sender) in a dispatch_async on the main thread, but, it is likely that there are other issues with the destination controller's code that we are not able to see here. 对此最“简单”的修复可能是在主线程上的dispatch_async self.performSegueWithIdentifier("loginSegue", sender: sender)的调用包装起来,但是,目标可能存在其他问题我们在这里看不到的控制器代码。

The issue is most likely that NSURLSession 's delegateQueue is not the main queue, and, something that [UIKeyboardTaskQueue waitUntilAllTasksAreFinished] is being called somewhere in that thread but it can only be called on the main thread. 问题很可能是NSURLSessiondelegateQueue不是主队列,并且在该线程的某处调用[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] ,但它只能在主线程上调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM