Swift 3 - 将数据传递回以前的视图控制器
Posted
技术标签:
【中文标题】Swift 3 - 将数据传递回以前的视图控制器【英文标题】:Swift 3 - passing data back to previous viewcontroller 【发布时间】:2017-03-02 19:06:53 【问题描述】:我知道之前有人问过这个问题,但我似乎无法弄清楚为什么在单击按钮并将字符串从 ViewControllerB 传递到 ViewController A 时应用程序崩溃时收到以下错误消息:
2017-03-02 12:42:02.485320 APPNAME[1111:2345678] -[ViewControllerA pressedNextButtonWithMessage:]:无法识别的选择器发送到实例 0x11fd7eb90 2017-03-02 12:42:02.589949 APPNAME[1111:2345678] 提供给 CFRunLoopRunSpecific 的无效模式 'kCFRunLoopCommonModes' - 中断 _CFRunLoopError_RunCalledWithInvalidMode 以进行调试。此消息每次执行只会出现一次。 2017-03-02 12:42:07.586960 APPNAME[1111:2345678] * 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[ViewControllerA pressedNextButtonWithMessage:]:无法识别的选择器发送到实例 0x11fd7eb90” * 首先抛出调用栈: (0x1819201c0 0x18035855c 0x181927278 0x181924078 0x18181e59c 0x100287824 0x1002878a0 0x18779e7b0 0x1879125ec 0x18779e7b0 0x18779e730 0x187788be4 0x187788d4c 0x18779e01c 0x18779db44 0x187798d8c 0x187769858 0x100159aec 0x187f56cb8 0x187f50720 0x1818ce278 0x1818cdbc0 0x1818cb7c0 0x1817fa048 0x18327d198 0x1877d4628 0x1877cf360 0x100077ef0 0x1807dc5b8) libc++abi.dylib:以 NSException 类型的未捕获异常终止
我的应用是 Swift 3 和传统 Objective-C 的混合体:
ViewControllerA.m
@interface ViewControllerA () <ViewControllerBDelegate>
@property (nonatomic, strong) NavViewController * navVC;
@end
@implementation ViewControllerA
- (void)viewDidLoad
...
self.navVC = [NavViewController instantiate]; // instantiate is a function that inits the storyboard and instantiates the viewcontroller from the NavViewController class
ViewControllerB *vcB = [self.navVC.viewControllers firstObject]; // ViewControllerB is actually the rootviewcontroller of navVC
vcB.delegate = self;
...
- (void)pressedNextButton:(NSString *)message
NSLog(@"Button worked: %@", message);
@end
ViewControllerB.swift
@objc protocol ViewControllerBDelegate
func pressedNextButton(message: String)
@objc class ViewControllerB: UIViewController, NSFetchedResultsControllerDelegate, UITableViewDataSource, UITableViewDelegate
var delegate: ViewControllerBDelegate?
var passedMessage: String = "Pass this message back to ViewControllerA"
@IBAction func nextButton(_ sender: UIBarButtonItem) // this is the button that causes the app to crash
self.delegate?.pressedNextButton(message: passedMessage) // app crashes after executing this line
错误发生在
之后self.delegate?.pressedNextButton(message:passedMessage)
被执行。此外,如果我从代码中删除了 'passedMessage' 变量和相关参数,控制台会确认 pressNextButton 函数正在执行而没有问题(即我可以在控制台中看到日志“Button working”)。任何人都可以看到导致应用崩溃的原因以及我该如何解决这个问题?
这是我的 nextButton IBOutlet 的 Connections Inspector 的屏幕截图:
【问题讨论】:
检查所有插座是否连接正确。 我猜你指的是'@IBAction func nextButton?如果是这样,我右键单击情节提要中的按钮并在 Connections Inspector 下,我可以确认“nextButton”按钮已连接到“Sent Actions”部分下的 ViewControllerB。我会用截图更新问题。 将您的 viewDidLoad 代码放入 prepareforsegue 方法中。我猜您的委托将为零。 我没有通过 segues 传递数据。相反,我使用委托将数据传递回之前的视图控制器(即 ViewControllerA)。 是的,我知道,但您的 var 委托:ViewControllerBDelegate?是可选的,因此它拥有 nil 值,当您点击 @IBAction func nextButton(_ sender: UIBarButtonItem) 您的委托为 nil.you 必须给您的委托一个值。 【参考方案1】:您的 Objective-C 和 Swift 消息签名不匹配。你有两个选择:
修复 Objective-C 代码
在你的 Objective-C 代码中,改变
- (void)pressedNextButton:(NSString *)message
到
- (void)pressedNextButtonWithMessage:(NSString *)message
或者,修复 Swift 代码
在你的 Swift 代码中,改变
func pressedNextButton(message: String)
到
func pressedNextButton(_ message: String)
【讨论】:
你好,马特。像魅力一样工作。您能解释一下为什么该解决方案有效以及您是如何发现问题的吗?非常感谢! 我发现了这个问题,因为 (1) 您发布了错误消息并且我阅读了它,并且 (2) 我知道方法签名是如何在 Swift 和 Objective-C 之间转换的。如果您想了解 (2),请阅读我的书:apeth.com/swiftBook/apa.html#_objective_c_methods — 请注意这里的真正寓意:不要谈论错误消息。 显示错误信息。对您来说,它可能看起来像 gobbledegook,但它可能包含其他人知道如何阅读的重要信息。 好点。谢谢你的提示。此外,如果选择在您的解决方案中遵循 Swift 更改,请务必更改:self.delegate?.pressedNextButton(message:passedMessage) 为 self.delegate?.pressedNextButton(passedMessage) 当然,签名的更改必须始终如一地进行,直到整个编译完成。但这在我的回答中被认为是理所当然的。 :)以上是关于Swift 3 - 将数据传递回以前的视图控制器的主要内容,如果未能解决你的问题,请参考以下文章
Swift:如何将数据传递给嵌入在 ContainerView 中的 PageViewController?
如何将数据传递给嵌套控制器(UIContainerView)?