0

为什么每当加载此视图时,以下内容会使我的应用程序崩溃?

-(void)loadView {
    UIButton *chooseSubjectButton = [[UIButton buttonWithType:UIButtonTypeDetailDisclosure] retain];
    [chooseSubjectButton addTarget:self action:@selector(chooseSubject) forControlEvents:UIControlEventTouchUpInside ];
    chooseSubjectButton.frame = CGRectMake(15.0f, 205.0f, 296.0f, 51.0f);
    [self.view addSubview:chooseSubjectButton];
}

任何帮助将不胜感激。

谢谢!

4

7 回答 7

6

我的猜测是,您的应用实际上并没有崩溃。它只是不断地重复调用该loadView方法,因为您错过了加载视图。在向self.view添加任何内容之前调用[super loadView]或创建视图并分配它。方便的方法是使用.self.view[super loadView]

- (void)loadView {

    [super loadView];
    // Your Code Here
}

编辑:这个答案看起来是错误的。请考虑访问是否可以调用 [super loadView]?正如@Denis Vert 在评论中指出的那样。

于 2011-05-27T12:48:48.090 回答
2

[super loadView]@Simon 指出的您的缺乏提示了另一个问题。

您是否使用关联的 .xib 文件加载此视图控制器?如果是这样,您可能的意思是在-viewDidLoad而不是在-viewLoad.

只是一个想法,因为我过去一直对此感到困惑。

于 2011-05-27T12:50:23.550 回答
1

好的,这里已经给出的答案有很多混乱......

首先,您不打电话是正确的[super loadView];,请参阅- (void)loadView

如果您重写此方法以手动创建视图,您应该这样做并将层次结构的根视图分配给视图属性。(您创建的视图应该是唯一的实例,并且不应与任何其他视图控制器对象共享。)此方法的自定义实现不应调用 super.

如果您真的打算使用loadView(即以编程方式创建视图,而不是从NIB),那么在您的实现中,您必须分配view控制器的属性。

此外,您不需要按照使用按钮的方式保留按钮,因为您将其添加为主视图的子视图(之后您的主视图将拥有它)。

基于这些考虑,您的方法将如下所示:

    -(void)loadView {
        CGRect frame = [[UIScreen mainScreen] applicationFrame]; // adjust to your needs
        UIView *rootView = [[UIView alloc] initWithFrame:frame];

        UIButton *chooseSubjectButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        chooseSubjectButton.frame = CGRectMake(15.0f, 205.0f, 296.0f, 51.0f);
        [chooseSubjectButton addTarget:self action:@selector(chooseSubject) forControlEvents:UIControlEventTouchUpInside];

        [rootView addSubview:chooseSubjectButton];

        self.view = rootView;
        [rootView release];
    }

当然,如果你使用 NIB 来定义你的根视图,你需要重写-viewDidLoad:以进行额外的配置。

希望这可以帮助。

于 2011-05-27T13:59:13.840 回答
0

尝试将该代码放在viewDidLoad. 初始化代码可以创建无限堆栈跟踪。虽然我不确定创建该按钮是否会触发崩溃。

如果我错了,任何人都可以纠正我

请参阅:iPhone SDK:loadView 和 viewDidLoad 有什么区别?

于 2011-05-27T12:47:50.460 回答
0
-(无效)加载视图
{
[超级负载视图];
UIButton *chooseSubjectButton = [[UIButton buttonWithType:UIButtonTypeDetailDisclosure] 保留];
[chooseSubjectButton addTarget:self action:@selector(chooseSubject) forControlEvents:UIControlEventTouchUpInside ];
选择主题按钮.frame = CGRectMake(15.0f, 205.0f, 296.0f, 51.0f);
[self.view addSubview:chooseSubjectButton];
}

希望这可以帮助

于 2011-05-27T13:10:30.600 回答
0

只是对于其他阅读此线程的人来说,Octy 说你永远不应该调用 [super loadView] 是正确的。我在这个页面上读过一些关于它的辩论。阅读 Octy 回答中发布的文档,第 28 页清楚地指出您不应该调用此方法。甚至解释了原因。这样做将使用默认名称(与类名相同)查找 nib。即使这个笔尖不存在,也是对处理能力的浪费。只需创建一个新的 UIView 并将其设置为 self.view。(参见本页示例)

只是想确保未来的读者知道这一点。我花了一段时间才弄清楚。

于 2011-07-02T01:36:24.350 回答
0

你得到一个无限循环,因为你在 loadView 中引用 self.view。当你调用 self.view,而 self.view 为 nil 时,会导致 loadView 再次被调用。创建循环。

如果你调用 [super loadView] 它将初始化 self.view 所以你看不到问题。

所以,实例化 self.view 自己,你会没事的。

希望这可以帮助。

于 2013-05-02T17:06:18.953 回答