以编程方式加载视图

Posted

技术标签:

【中文标题】以编程方式加载视图【英文标题】:Loading view programmatically 【发布时间】:2015-09-14 18:13:16 【问题描述】:

我的项目中有三个视图控制器。我们称它们为 view1、view2 和 view3。 View2 是使用界面生成器中的 segue 从 View1 加载的。但是 view3 需要以编程方式从 view2 加载,因为 view2 向 REST 服务器发出 RESTful 请求并且该请求是异步的。我有一个单独的类来处理 REST 请求。从 REST 服务器获得返回值后,我调用 view2 的 loadResultViewController 方法。但是,我收到“libc++abi.dylib:以 NSException 类型的未捕获异常终止”错误。我该如何解决这个问题?

这是我的 loadResultViewController 方法

func loadResultViewController(summary: String) 
    let resultViewController = self.storyboard!.instantiateViewControllerWithIdentifier("ResultView") as! ResultViewController
    self.presentViewController(resultViewController, animated: true, completion: nil)
    resultViewController.summary.text = summary

 

编辑:

这是完整的错误消息。

2015-09-14 14:01:13.645 My Strategic[5307:791826] * -[UIKeyboardTaskQueue waitUntilAllTask​​sAreFinished]、/SourceCache/UIKit_Sim/UIKit-3347.44.2/Keyboard/UIKeyboardTaskQueue.m 中的断言失败: 374 2015-09-14 14:01:13.678 我的战略 [5307:791826] * 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“-[UIKeyboardTaskQueue waitUntilAllTask​​sAreFinished] 只能从主线程调用。” *** 首先抛出调用堆栈: ( 0 CoreFoundation 0x000000010345dc65 异常预处理+ 165 1 libobjc.A.dylib 0x0000000104fc8bb7 objc_exception_throw + 45 2 CoreFoundation 0x000000010345daca +[NSException raise:format:arguments:] + 106 3 基础 0x00000001038fa98f -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195 4 UIKit 0x00000001044547d6-[UIKeyboardTaskQueue waitUntilAllTask​​sAreFinished] + 151 5 UIKit 0x0000000103ef5912-[UIKeyboardImpl setDelegate:force:] + 473 6 UIKit 0x00000001041a04ad-[UIPeripheralHost(UIKitInternal)_reloadInputViewsForResponder:] + 1002 7 UIKit 0x00000001041a8834-[UIPeripheralHost(UIKitInternal)_preserveInputViewsWithId:animated:reset:] + 504 8 UIKit 0x0000000103e384f1-[UIViewController _presentViewController:modalSourceViewController:presentationController:animationController:interactionController:completion:] + 623 9 UIKit 0x0000000103e3976e-[UIViewController _presentViewController:withAnimationController:completion:] + 3079 10 UIKit 0x0000000103e3b6c1 __62-[UIViewController presentViewController:animated:completion:]_block_invoke + 132 11 UIKit 0x0000000103e3b5e5-[UIViewController presentViewController:animated:completion:] + 229 12 我的战略 0x0000000102dbfc26 _TFC14My_Strategic22PostCodeViewController24loadResultViewControllerfS0_FSST_ + 870 13 我的战略 0x0000000102dc0cae _TTWC14My_Strategic22PostCodeViewControllerS_12RestDelegateS_FS1_24loadResultViewControllerUS1___fQPS1_FSST_ + 94 14 我的战略 0x0000000102dcfcf0 _TFFC14My_Strategic4Rest9getRidingFS0_FSST_U_FTGSQCSo13NSURLResponse_GSQCSo6NSData_GSQCSo7NSError__T_ + 2960 15 我的战略 0x0000000102dcfe4a _TTRXFo_oGSQCSo13NSURLResponse_oGSQCSo6NSData_oGSQCSo7NSError__dT__XFdCb_dGSQS__dGSQS0__dGSQS1___dT + 90 16 CFNetwork 0x000000010566d8c5 67+[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]_block_invoke_2 + 155 17 基础 0x000000010391e57f __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK + 7 18 基础 0x000000010385f0b2 -[NSBlockOperation main] + 98 19 基础 0x0000000103841774 -[__NSOperationInternal _start:] + 645 20 基础 0x0000000103841383 __NSOQSchedule_f + 184 21 libdispatch.dylib 0x0000000106ac2614 _dispatch_client_callout + 8 22 libdispatch.dylib 0x0000000106aa96a7 _dispatch_queue_drain + 2176 23 libdispatch.dylib 0x0000000106aa8cc0 _dispatch_queue_invoke + 235 24 libdispatch.dylib 0x0000000106aac3b9 _dispatch_root_queue_drain + 1359 25 libdispatch.dylib 0x0000000106aadb17 _dispatch_worker_thread3 + 111 26 libsystem_pthread.dylib 0x0000000106e2f637 _pthread_wqthread + 729 27 libsystem_pthread.dylib 0x0000000106e2d40d start_wqthread + 13 ) libc++abi.dylib:以 NSException 类型的未捕获异常终止

【问题讨论】:

您能否发布您收到的完整错误消息? 你尝试了什么?您是否看到您的回复到达并正确解析它?你确定你的完成处理程序被调用来触发你的segue吗?您是否尝试在不等待响应的情况下调用您的 segue(即创建一个按钮来触发您的 segue)。 是的,它解析正确。在 presentviewcontroller 调用中出现异常。 view2 和 view3 之间没有segue。我需要一个吗? 【参考方案1】:

这是错误信息的相关部分:

原因:'-[UIKeyboardTaskQueue waitUntilAllTask​​sAreFinished] 只能从主线程调用。'

您在后台线程上发出 REST 请求,然后当您获得结果时,您在同一线程上执行转换。所有 UI 代码通常都应该在主线程上运行。

尝试将代码封装在方法体中:

dispatch_async(dispatch_get_main_queue(),
  // your code here
)

【讨论】:

我从 NSURLConnection.sendAsynchronousRequest 的回调函数中调用我的 loadResultViewController 因为我不知道在收到数据后加载新视图的其他方法。无论如何,我将 REST 请求代码放入您的包装代码中,但仍然出现异常。 如果您根据@rkunde 的回答更新了代码,它应该可以解决您的问题。如果您仍然遇到错误,请在您的问题中添加一个新部分,显示您的新代码,指出哪一行出现错误,以及错误消息的全文。 我的错,我把 REST 函数放在里面,而不是加载新视图的代码。它有效!【参考方案2】:

建议中的小错字.. 表达式块应以 '^' 为前缀,如下所示

dispatch_async(dispatch_get_main_queue(), ^
    // your code here
)

【讨论】:

以上是关于以编程方式加载视图的主要内容,如果未能解决你的问题,请参考以下文章

使用 Swift 以编程方式插入按钮并加载第二个视图

以编程方式在主视图控制器上加载模态视图控制器

以编程方式将视图加载到 UIViewController

以编程方式加载自定义子视图,就像它们是单元格一样?

从情节提要重新加载视图时,以编程方式添加的 iOS 子视图会丢失

如何以编程方式将自定义 Java 视图类加载到 RelativeLayout