【问题标题】:Segue throwing NSInternalInconsistencyException, with NSURLConnection sendAsynchronousRequestSegue 抛出 NSInternalInconsistencyException,使用 NSURLConnection sendAsynchronousRequest
【发布时间】:2014-05-12 01:07:13
【问题描述】:

因此,我一直在尝试为网站创建应用程序,并且“登录”页面正常工作,除非它不会转换到下一个视图。

这是我认为导致问题的代码:

NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
 {
     NSString *str=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
     //NSLog(@"%@", str);
     if ([str rangeOfString:@"The username or password you provided is invalid. Please try again."].location == NSNotFound) {
         loginPageStatusLabel.text = @"Correct";
         NSLog(@"Correct Login");

         [self performSegueWithIdentifier:@"toHome" sender:self];


     } else {
         loginPageStatusLabel.text = @"Incorrect";
         NSLog(@"Login Failed");
     }

 }];

* -[UIKeyboardTaskQueue waitUntilAllTask​​sAreFinished] 中的断言失败,/SourceCache/UIKit_Sim/UIKit-2935.137/Keyboard/UIKeyboardTaskQueue.m:368 2014-05-11 00:06:51.426 LoginTests[3381:3e03] * 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“-[UIKeyboardTaskQueue waitUntilAllTask​​sAreFinished]”只能从主线程调用。 waitUntilAllTask​​sAreFinished]' 只能从主线程调用。

这是每当我尝试“登录”时引发的错误。如果我单独运行它,则 Segue 可以工作,所以我假设问题是应用程序在准备好之前试图转到下一个视图并导致错误。

我对 Obj-C 还很陌生,所以如果我没有发布足够的信息或没有用正确的名称称呼事物,请通知我。

谢谢!

【问题讨论】:

  • 与您手头的问题无关,但我会非常警惕在没有“无效”消息的情况下得出成功的结论。有很多错误可能不会导致该消息。您应该确定区分成功的因素,然后寻找它,而不是在没有特定错误消息的情况下得出成功的结论。
  • 我如何确定成功的区别?我知道我现在检查的方式不是最好的方式,但据我所知,没有 API,这是唯一的方式。
  • 首先,您应该检查以确保data 不是nil。其次,您要确保response 对象的statusCode200。第三,不是检查特定的错误消息,而是确定 Web 服务器在成功时将响应的唯一内容,并检查它(而不是寻找一种特定类型的错误,实际上,可能有许多不同类型的错误)错误)。
  • 我明白了,这是一个很好的建议,我一定会遵循的。是否有图书馆或网络抓取的东西?
  • 在您深入研究时可能有用的一个库是 HTML 解析器,例如 HPPLE。看到这个Wenderlich introduction to parsing HTML

标签: ios objective-c nsurlconnection


【解决方案1】:

我不知道您为 queue 参数提供了什么值,但鉴于您的完成块正在执行必须在主线程上发生的 UI 更新,您可以使用 [NSOperationQueue mainQueue](或手动将此代码分派到主队列)。这个queue 参数指定完成块应该添加到哪个队列,并且因为您在完成块中执行与 UI 相关的内容,所以必须在主线程上完成。

更正后,如果您仍然有断言错误,您可以添加exception breakpoint,这将有助于准确确认此断言错误发生的位置。或者查看您的堆栈跟踪。

除了使用[NSOperationQueue mainQueue],我还建议做一些更强大的错误处理:

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
 {
     if (!data) {
         // for example, no internet connection or your web server is down

         NSLog(@"request failed: %@", error);
         return;
     }

     if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
         int statusCode = [(NSHTTPURLResponse *)response statusCode];

         if (statusCode != 200) {
             // for example, 404 would mean that your web site said it couldn't find the URL
             // anything besides 200 means that there was some fundamental web server error

             NSLog(@"request resulted in statusCode of %d", statusCode);
             return;
         }
     }

     // if we got here, we know the request was sent and processed by the web server, so now
     // let's see if the login was successful.

     NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

     // I'm looking for "Welcome" ... I doubt that's right (but I don't have access to 
     // your web server, so I'm guessing). But the idea is that you have to find whatever
     // appears after successful login that is not in the response if login failed

     if ([responseString rangeOfString:@"Welcome"].location != NSNotFound) {
         loginPageStatusLabel.text = @"Correct";
         NSLog(@"Correct Login");

         [self performSegueWithIdentifier:@"toHome" sender:self];
     } else {
         loginPageStatusLabel.text = @"Incorrect";
         NSLog(@"Login Failed");
     }
 }];

【讨论】:

  • 我在编辑中添加了队列代码。好的,我可以使用此代码 [[NSOperationQueue mainQueue] addOperationWithBlock:^{ [self performSegueWithIdentifier:@"toHome" sender:self]; }];这是正确的吗?
  • @user3624962 是的,这行得通。或者,更简单的是,根本不要 alloc/init 一个新的 NSOperationQueue,而只是使用 [NSOperationQueue mainQueue] 作为 queue 参数到您的 sendAsynchronousRequest 调用。
猜你喜欢
  • 2014-09-26
  • 1970-01-01
  • 1970-01-01
  • 2017-09-02
  • 2015-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多