【问题标题】:Pushing UIViewController fails with "Application tried to push a nil view controller on target"推送 UIViewController 失败并显示“应用程序试图在目标上推送 nil 视图控制器”
【发布时间】:2015-10-26 23:43:02
【问题描述】:

所以我使用 NavigationController 来完成我的 iOS 应用程序的所有导航。在主屏幕上有一个“加号按钮”来拍摄图像,按下此按钮时,NavigationController 会使用“displayCamera:”方法推动“CameraViewController”。在那里,用户可以拍摄图像,并且应该由另一个 UIViewController 预览,该 UIViewController 由函数 'picTaken:' 推送。但是加班时我尝试推送此视图控制器我收到错误“应用程序试图在目标上推送一个 nil 视图控制器”。我不知道出了什么问题。下面是 NavigationController.h 和对应的 .m 文件


导航控制器.h

#import <UIKit/UIKit.h>

#import "CameraViewController.h"
#import "MainViewController.h"
#import "PictureCheckViewController.h"

@interface NavigationController : UINavigationController {
    CameraViewController *camView;
    MainViewController *mainView;
    PictureCheckViewController *checkView;
}

- (void)displayCamera:(id)sender;

- (void)picTaken:(id)sender;

@end

导航控制器.m

#import "NavigationController.h"

@interface NavigationController () {

}

@end

@implementation NavigationController

- (void)viewDidLoad
{
    [super viewDidLoad];
    camView = [[CameraViewController alloc] init];
    mainView = [[MainViewController alloc] init];
    checkView = [[PictureCheckViewController alloc] init];

}

 - (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)displayCamera:(id)sender {
    [self pushViewController:camView animated:YES];
}

- (void)picTaken:(id)sender {
    [self pushViewController:checkView animated:YES];
}

@end

如果您需要更多信息,请告诉我。

感谢您的时间和帮助:)

【问题讨论】:

  • 如果你调用 picTaken 会发生同样的事情吗?
  • 嘿抱歉,我只是注意到我没有澄清这一点。首先打开cameraView,我调用函数displayCamera:,它工作正常,没问题。当我稍后想调用picTaken: 然后它抛出错误时,就会出现问题。很抱歉给您带来不便。
  • 你能用断点检查实例是否真的为零吗?
  • 所以我只检查了 2 个断点。我分配和初始化断点的点打印实例。但是我在函数中的第二个断点打印为零。为什么会发生这种情况?我应该将它们添加为属性并建立强连接吗?
  • iVar 应该是强引用。你在用ARC吗?你应该。

标签: ios objective-c uiviewcontroller uinavigationcontroller


【解决方案1】:

我建议您使用惰性实例化方法。 添加属性:

@Property(nonatomic,strong) MainViewController *mainView;
@Property(nonatomic,strong) PictureCheckViewController *checkView;

并自己覆盖 getter:

-(MainViewController*) mainView {
    if(!_mainView) {
        _mainView = [[MainViewController alloc] init];
    }
    return _mainView;
}

checkView 也是如此。

-(PictureCheckViewController*) checkView {
    if(!_checkView) {
        _checkView = [[PictureCheckViewController alloc] init];
    }
    return _checkView;
}

然后使用:

self.checkView
self.mainView

除了我相信可以解决您的问题之外,它还可以避免创建,除非资源被实际使用。

【讨论】:

  • 是的,有效,我没有收到错误。视图仍然没有出现,但我会继续调试并尝试找出原因。非常感谢你!就像额外的信息一样,既然我只是自学编码,为什么这就是惰性实例化的原因?非懒惰的方式是什么?为什么最好覆盖 getter 而不是使用@synthesize?非常感谢您的帮助,非常感谢您的快速回复。
  • 当然可以。它是懒惰的,因为你 覆盖了它。该值直到第一次被请求时才被初始化(因此是 if 语句)。请记住,swift(以及我认为自 iOS 5 以来的现代 Objective-c)无论如何都是自动合成的。如果您不调用 getter,则永远不会设置该值。并在其后缓存。
猜你喜欢
  • 2014-09-16
  • 1970-01-01
  • 2012-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多