视图控制器中的延迟实例化

3
我有一个按钮,可以从类的数组中触发随机声音。我在视图控制器中使用了延迟实例化,它由IBAction触发,但我感觉这是不正确的,因为有两个原因:
1)通常我看到人们在getter和setter中进行L.I.。
当我尝试在getter/setter中进行L.I.时,我的程序会崩溃,我不知道为什么。
2)我正在执行这个延迟实例化,在视图控制器的IBAction中。
这样做延迟实例化的方式是否正确?
以下是不会崩溃的代码:
- (IBAction)myClass:(UIButton *)sender
{

    if (!self.myClass){
        self.myClass = [[myClass alloc] init];
        [self.myClass setUpMyClass]; // this method just loads sounds and some text
    }


    [self.myClass playSound];
    self.myClassLabel.text = [[NSString alloc] initWithFormat:@"%@", [self.myClass someText]];

}

以下是导致程序崩溃的代码:

- (myClass *)myClass
{

    if (!self.myClass){
        self.myClass = [[myClass alloc] init];
        [self.myClass setUpMyClass]; // this method just loads sounds and some text
    }

    return self.myClass;
}

- (IBAction)myClass:(UIButton *)sender
{
    [self.myClass playSound];
    self.myClassLabel.text = [[NSString alloc] initWithFormat:@"%@", [self.myClass someText]];

}

调试器中的输出并没有提供太多信息,但是在一行代码旁边有一个绿色箭头。
-(myClass *) myClass {

并且它说

Thread 1: EXC_BAD_ACCESS (code=2, address =0xbf7ffffc)

对于用户名为aqua的用户,setUpMyMethod方法是这样的:

-(void) setUpEscha{
    self.eschaDialogue = [[NSArray alloc] initWithObjects:
                       [[NSBundle mainBundle] pathForResource:@"Sound1" ofType:@"mp3"],
                       [[NSBundle mainBundle] pathForResource:@"Sound1" ofType:@"mp3"],
                       ...
                       nil];

self.eschaLines = [[NSArray alloc] initWithObjects:
                    @"String1",
                    @"String2",
                    @"...",
                    nil];

}


1
你的代码总体看起来不错。但是如果你想得到真正的帮助,你需要在问题中更新关于崩溃的确切细节。包括错误和堆栈跟踪。 - rmaddy
1
您能够提供调试器的信息或者展示setUpMyClass函数的代码吗? - aqua
1
旁注:最后一行应为:self.myClassLabel.text = [self.myClass someText];。这假设 [self.myClass someText] 返回一个 NSString - rmaddy
@aqua 方法“setUpMyClass”不是问题,但如果你必须知道它所做的就是设置两个数组,一个包含声音,另一个包含字符串。请看上面。 - Moose
1个回答

4

您的getter函数在递归调用自身。不要在myClass getter内访问self.myClass。请将您的代码更改为:

- (myClass *)myClass
{
    if (!_myClass){
        _myClass = [[myClass alloc] init];
        [_myClass setUpMyClass]; // this method just loads sounds and some text
    }
    return _myClass;
}

这里假设你的 myClass 的 iVar 是 _myClass。如果不是,请将 _myClass 更改为该 iVar 名称。
对于类似 "为什么 XXX 会崩溃" 的未来问题,如果您包含来自崩溃的调试器日志和堆栈跟踪,则会很有帮助。

如何查看堆栈跟踪? - Moose
1
无论属性是公有的还是私有的,只要正确引用了iVar,这个问题就应该解决了。如果你仍然遇到困难,你需要发布声明iVar、属性和任何与之相关的@synthesize语句的代码。 - XJones
我已经修复了,我将它更改为self._myClass时应该是_myClass。现在它可以正常工作了。谢谢! - Moose
1
好的,太棒了。我不需要再添加更多的答案了。我相信在SO上有一些关于如何在Xcode中查看堆栈跟踪的好的问答... :) 祝编码愉快。 - XJones

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接