prepareForSegue 在模拟器上工作但不在设备上

Posted

技术标签:

【中文标题】prepareForSegue 在模拟器上工作但不在设备上【英文标题】:prepareForSegue working on simulator but not on device 【发布时间】:2015-02-28 12:34:03 【问题描述】:

我厌倦了尝试完成这项工作,所以我希望这里有人能够为我解决这个问题..

我正在使用此代码连接到 UINavigationController。此代码在模拟器上有效,但在真实设备上

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

    static NSString *segueIdentifier = @"ShowDetails";

    if ([[segue identifier] isEqualToString:segueIdentifier]) 

        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];

        UINavigationController *navigationController = segue.destinationViewController;
        DetailViewController *detailViewController = [navigationController viewControllers][0];


        detailViewController.selectedGameIdNumber = [NSString stringWithFormat: @"%ld", (long)indexPath.row];
        detailViewController.selectedSection = [self.sectionNames objectAtIndex:indexPath.section];
    

在真实设备上崩溃:

 DetailViewController *detailViewController = [navigationController viewControllers][0];

出现错误:

-[DetailViewController viewControllers]: unrecognized selector sent to instance

然后我尝试了这段代码。此代码在设备上有效,但在模拟器上

  -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

    static NSString *segueIdentifier = @"ShowDetails";

    if ([[segue identifier] isEqualToString:segueIdentifier]) 

        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];

        DetailViewController * detailViewController = (DetailViewController *)segue.destinationViewController;


        detailViewController.selectedGameIdNumber = [NSString stringWithFormat: @"%ld", (long)indexPath.row];
        detailViewController.selectedSection = [self.sectionNames objectAtIndex:indexPath.section];
    

在模拟器上崩溃:

detailViewController.selectedGameIdNumber = [NSString stringWithFormat: @"%ld", (long)indexPath.row];

出现错误:

 -[UINavigationController setSelectedGameIdNumber:]: unrecognized selector sent to instance 0x7fa1d273e8

我是不是做错了什么,还是应该只使用在真实设备上运行的第二个代码? 我想要一个干净的解决方案,所以如果我做错了什么,请赐教。谢谢大家。

【问题讨论】:

哪个模拟器/ios版本,哪个设备/iOS版本?我怀疑答案是您必须针对这两种情况进行防御性编码(即使用isKindOfClass: 测试目标视图控制器的类并相应地处理每种情况)。 模拟器的部署目标设置为 7.1,我的设备运行在 IOS 7.1.1 iPhone 5s @pbasdf 模拟器也运行 7.1 吗? (部署目标有所不同)正在模拟哪个设备? 项目文件名@pbasdf中写着IOS SDK 8.1 我怀疑它可能是 iOS8 - Apple 改变了 iOS8 中 segues 的工作方式。正如我之前建议的那样,为了适应这两种情况,请检查 segue 的 destinationViewController 的类 - 如果是 [UINavigationController class],则使用上面的第一个代码块,如果是 [DetailViewController class],则使用你的第二个代码块。 【参考方案1】:

问题在于您如何访问视图控制器。在设备上,视图控制器层次结构与模拟器上的不同,因此这两种解决方案都只能在各自的场景中工作。当然不同的不是模拟器,而是你模拟的设备(猜是iPad)

请注意,特别是对于 splitViewcontrollers,但对于其他框架提供的视图控制器,控制器的功能可能会因目标设备而异。当您对视图控制器等的索引做出假设时,这种更改通常会影响您。

在模拟器上调试,在设备类型和视图控制器之间切换,我想你会明白我的意思的。

【讨论】:

【参考方案2】:

这是我的解决方案:创建一个通用结构并通过函数调用转换自定义的视图控制器。优点是您可以在需要的任何地方重用此功能。 (虽然我的代码是用swift而不是Objective-C编写的,但我认为解决方法是一样的)

struct DestinationController<T: UIViewController> 
    func get(segue: UIStoryboardSegue) -> T 
        if let navigation = segue.destinationViewController as? UINavigationController
            return navigation.viewControllers.first as! T
        
        return segue.destinationViewController as! T
    

【讨论】:

以上是关于prepareForSegue 在模拟器上工作但不在设备上的主要内容,如果未能解决你的问题,请参考以下文章

prepareForSegue 里面的函数不会执行

覆盖 prepareForSegue 函数时 IBAction 中的线程错误

覆盖 prepareForSegue 函数时 IBAction 中的线程错误

iAd 横幅显示在模拟器上,但不显示在设备上

自动布局约束已应用但不工作

android:在模拟器中工作但不在手机上的联系人提供程序