简体   繁体   中英

Pushing ViewController gives NSInvalidArgumentException

I'm a newbie iOS developer, recently developed several Android apps, but I'm not familiar with iOS jargon. Let me explain my problem.

I want to use two different UIViewController . I've created .h and .m files for both controller. My plan is to push the secont view controller on top of the first view controller five seconds after the first view controller appears on the screen. I mean the first view controller is something like splash screen or similar.

Here is my contribution. In the first view controller, I defined (one of them implemented of course) these two method:

-(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];
}

And the second view controller looks like this:

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

I've changed only viewDidLoad method. When I ran the simulator, first view controller worked well and waiting 5 seconds and crashed. Output looks like:

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'

Let me ask one more question: I know there are differences between methodName and methodName: . Can anyone explain what's difference?

Any help would be appreciated.

UPDATE:

- (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;
}

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

As mentioned above, you probably want to change your performSelector command to:

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

because you want it to call your pushSecondController method, and not pushViewController:animated: .

Regarding your second question: the difference between methodName and methodName: is that the : at the end of methodName: signifies that this method takes a parameter. So, you could have the following methods:

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

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

When passing a reference to them into @selector , for the first method you'd just do @selector(listItems) , because it takes no parameters, and for the latter you'd do @selector(insertItem:) because it takes a parameter.

UPDATE

Just saw your applicationDidLaunch code. You probably want to rearrange things so that you add your ViewController to your UINavigationController , and then set the UINavigationController as the rootViewController of your window. Like so:

- (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;
}

please change your didFinishLaunchingWithOptions method to:

   - (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;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM