以编程方式调用 segue 导致 NSInvalidArgumentException,原因:'UILabel 长度'无法识别的选择器

Posted

技术标签:

【中文标题】以编程方式调用 segue 导致 NSInvalidArgumentException,原因:\'UILabel 长度\'无法识别的选择器【英文标题】:Programmatically call a segue cause NSInvalidArgumentException, reason: 'UILabel length' unrecognized selector以编程方式调用 segue 导致 NSInvalidArgumentException,原因:'UILabel 长度'无法识别的选择器 【发布时间】:2012-10-04 13:40:01 【问题描述】:

我正在尝试进行条件转场。但我明白了:

    Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UILabel length]: unrecognized selector sent to instance 0x763c8e0'

设计是,当我按下按钮时,应用程序将使用 AFNetworking 的 AFJSONRequestOperation 从互联网检索一些数据。如果请求成功,它将从我当前的 UIViewController 调用另一个 UIViewController。我使用this method 进行了有条件的启动segue,以下是我的代码:

-(void) login:(NSString*)pinString    
NSString* urlString = [NSString stringWithFormat:@"%@%@%@", [super.serverResource getURL], [super.serverResource getRequestByKey:@"login"] ,pinString];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];    
AFJSONRequestOperation *operation = [MenuletJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) 
    [self performSegueWithIdentifier:@"login" sender:self];
 failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON)
    switch([response statusCode])
        case (403):
            UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Log in failed"
                                                      message:@"Log in denied, check your PIN."
                                                      delegate:nil cancelButtonTitle:@"OK"
                                                      otherButtonTitles:nil];
            [alert show];
            break;
        
    
];
[operation start];

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
SettingViewController *settingVC = (SettingViewController*)[storyboard instantiateViewControllerWithIdentifier:@"SettingViewController"];
[self presentViewController:settingVC animated:YES completion:nil];

在 SettingViewController 中执行“ViewDidLoad”后出现上述异常。如果我不使用条件转场,而只是 ctl 从 Button 拖动到 IB 上的 SettingViewController,一切正常...请给我一些建议...我真的没有想法...

以下是来自 SettingViewController 的代码:

- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view.
//StringResources* resource = [[StringResources alloc]init];
[self.titleLabel setText:[super.stringResource getStringByKey:@"screen_setting_title"]];
[self.createOrderLabel setText:[super.stringResource getStringByKey:@"screen_setting_create_order_label"]];
[self.refreshMenuLabel setText:[super.stringResource getStringByKey:@"screen_setting_refresh_menu_label"]];
[self.tableNumberLabel setText:[super.stringResource getStringByKey:@"screen_setting_table_number_label"]];

实际上,我并没有在 SettingViewController 中放太多东西,我所做的只是以编程方式设置一些标签。我在每个 setText 上都设置了断点,它们都执行没有错误。所以异常一定是发生在ViewDidLoad之后...

这是发生错误的地方:

#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char *argv[])

    @autoreleasepool 
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); //error occur here
    

已解决...原来 Segue 可以处理所有问题。我需要做的就是设置一个通用的segue。一旦我调用 [self performSegueWithIdentifier:@"login" sender:self],一切正常。谢谢大家...(覆盖 prepareForSegue 只会导致问题...)

【问题讨论】:

这非常令人困惑。你期望在这里发生什么?你正处于一个 segue 的中间,然后你打断它来呈现一个模态视图控制器。当前视图控制器、目标视图控制器和您从情节提要加载的第三个视图控制器之间有什么关系? 对不起,我没有说清楚。我在 IB 上创建了一个通用的 segue(因为我在某处读到我无法从任何地方启动另一个 ViewController)。所以我原来的segue不应该做任何事情。当我按下按钮时,1. 它应该使用 AFNetworking 验证请求。 2. 如果响应正确,则使用 performSegueWithIdentifier 调用通用 segue。 3. 它应该调用prepareForSegue。 4. 它从情节提要启动 SettingViewController 并将其显示在屏幕上......至少这是我打算做的 Segues 总是做一些事情。有一个目标视图控制器。该视图控制器正在加载并转换到。如果您手动加载呈现视图控制器,则不要使用 segue。 那么我应该如何显示另一个 ViewContoller?我只做过 IB 的事情...不知道如何以编程方式进行... 【参考方案1】:

选项 1:相信转场

确保 segue 从您当前的视图控制器转到 SettingViewController。

然后你保留-performSegueWithIdentifier:sender:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
   // load data from current view controller to segue.destinationViewController

选项 2:手动加载模态视图控制器

把segue全部扔掉,只从storyboard加载视图控制器。

AFJSONRequestOperation *operation = [MenuletJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) 
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    SettingViewController *settingVC = (SettingViewController*)[storyboard instantiateViewControllerWithIdentifier:@"SettingViewController"];
    // load data from current view controller to settingVC
    [self presentViewController:settingVC animated:YES completion:nil];
 failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON)
    // Error handler
];

【讨论】:

我使用了第二个选项,效果很好。谢谢你。知道为什么以编程方式在 segue 中启动 ViewController 会导致这样的问题吗?? 我猜是因为您在执行 segue 的过程中手动加载模态视图控制器而中断了正常的加载周期。 有趣的事情...我尝试使用 Storyboard 方法启动 SettingViewController。使用相同的代码,如果我在 AFJSONRequestOperation 中调用它,它可以正常工作。如果我在 performSegueWithIdentifier 中调用它,它可以正常工作。但是如果我把它放在 prepareForSegue 里面,它就崩溃了……【参考方案2】:

您想要做的是从 ViewController(橙色背景图标上的白色方块)单击并拖动,这将创建通用序列。然后你可以从代码中调用它。在 prepareForSegue 中,您可以访问您的目标 VC:

  segue.destinationViewController

并在那里加载数据或设置您想要的任何属性。我确实相信这是解决此问题的推荐方法。

【讨论】:

我相信你是从故事板上分配和实例化一个 VC。你不必那样做。您只需使用 segues 属性目标 VC 访问它。这将返回 UIViewContoller,您可以将其转换为您的自定义 VC,例如:CustomVC *customVC=segue.destinationViewController。您不必担心创建或呈现 VC,只需在其上设置数据,segue 会负责休息,我认为您通过尝试呈现您在故事板中加载的另一个 VC 来制造冲突,而 segue 试图呈现它自己的另一个实例 哦,对不起,我忘了说,这是我以前做过的,但我得到了同样的错误。这就是为什么我尝试使用故事板启动,并想知道它是否有所作为......(我没有) 有趣的事情...我尝试使用 Storyboard 方法启动 SettingViewController。使用相同的代码,如果我在 AFJSONRequestOperation 中调用它,它可以正常工作。如果我在 performSegueWithIdentifier 中调用它,它可以正常工作。但是如果我把它放在 prepareForSegue 里面,它就崩溃了…… 那是我的另一点。您根本不应该在 prepareForSegue 中调用 presentViewController,因为 segue 正在为您呈现它。 好的...解决了...问题是因为我认为我需要自己启动所有事情...并且没有意识到 segue 为我处理所有事情...我所需要的只是 [self performSegueWithIdentifier:@"login" sender:self];...在删除其他所有内容后...它工作得很好...非常感谢...【参考方案3】:

由于您在新 VC 上的 viewDidLoad 中遇到异常,我猜 segue 工作正常,问题出在新 VC 实现中。

看到错误,您是否直接在 UILabel 对象上使用类似 isEqualToString 之类的 NSString 比较而不是其文本属性?

嗯.. 如果您发布一些 SettingViewController 的代码引用导致崩溃的 UILabel,我们可以帮助您。

【讨论】:

【参考方案4】:

今天我也遇到了这个错误。我不知道是什么原因造成的,我认为这是一个 Xcode 错误。通过删除 segue 并重新创建它(通过 CTRL 将其从 viewcontroller 拖动到 viewcontroller)来删除它。

我喜欢 Xcode,但有时它让我发疯。

【讨论】:

以上是关于以编程方式调用 segue 导致 NSInvalidArgumentException,原因:'UILabel 长度'无法识别的选择器的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式展开 segue

以编程方式定义和执行 segue

从 CollectionView Cell 以编程方式执行 Segue

无法以编程方式执行 segue

在 watchOS 上以编程方式触发 segue

如何以编程方式执行Unwind segue?