推送ViewController会产生NSInvalidArgumentException

时间:2012-08-24 08:12:48

标签: ios

我是一名新手iOS开发者,最近开发了几款Android应用程序,但我不熟悉iOS行话。让我解释一下我的问题。

我想使用两个不同的UIViewController。我为这两个控制器创建了.h.m个文件。我的计划是在第一个视图控制器出现在屏幕上五秒后将secont视图控制器推到第一个视图控制器的顶部。我的意思是第一个视图控制器就像闪屏或类似的东西。

这是我的贡献。在第一个视图控制器中,我定义了(其中一个当然是实现的)这两个方法:

-(void) pushSecondController {
    SecondViewController *secondController = [[SecondViewController alloc]
                                              initWithNibName: nil
                                              bundle: NULL];
    [self.navigationController pushViewController: secondController animated: YES];
}

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self performSelector: @selector(pushViewController:animated:)
                withObject: nil
                afterDelay: 5.0f];
}

第二个视图控制器如下所示:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    self.title = @"Second Controller";
}

我只更改了viewDidLoad方法。当我运行模拟器时,第一个视图控制器运行良好,等待5秒钟然后崩溃。输出如下:

2012-08-24 10:46:34.104 NavApplication[20355:f803] -[ViewController pushViewController:]: unrecognized selector sent to instance 0x6e7f780
2012-08-24 10:46:34.107 NavApplication[20355:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ViewController pushViewController:]: unrecognized selector sent to instance 0x6e7f780'

让我再问一个问题:我知道methodNamemethodName:之间存在差异。谁能解释一下有什么区别?

任何帮助都将不胜感激。

更新

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    self.navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
    [self.window makeKeyAndVisible];
    [self.window addSubview: self.navigationController.view];
    return YES;
}

3 个答案:

答案 0 :(得分:3)

@selector(pushViewController:animated:)更改为@selector(pushSecondController)

答案 1 :(得分:3)

如上所述,您可能希望将performSelector命令更改为:

[self performSelector: @selector(pushSecondController)
            withObject: nil
            afterDelay: 5.0f];

因为您希望它调用pushSecondController方法,而不是pushViewController:animated:

关于您的第二个问题:methodNamemethodName:之间的区别在于:末尾的methodName:表示此方法采用参数。所以,你可以有以下方法:

- (void)listItems
{
    // ...
}

- (void)insertItem:(NSDictionary *)item
{
    // ...
}

将对它们的引用传递给@selector时,对于第一种方法,您只需执行@selector(listItems),因为它不需要参数,对于后者,您需要执行@selector(insertItem:)因为它需要一个参数。

<强>更新

刚看到您的applicationDidLaunch代码。您可能希望重新排列内容,以便将ViewController添加到UINavigationController,然后将UINavigationController设置为窗口的rootViewController。像这样:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.

    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    self.navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController];

    self.window.rootViewController = self.navigationController;

    [self.window makeKeyAndVisible];
    return YES;
}

答案 2 :(得分:0)

请将您的didFinishLaunchingWithOptions方法更改为:

   - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        // Override point for customization after application launch.
        self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
        self.navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController];

            self.window.rootViewController = self.navigationController;

            [self.window makeKeyAndVisible];

            return YES;
    }