在initWithNibName之前调用ViewDidLoad?

时间:2011-02-01 11:17:12

标签: iphone objective-c

我遇到了最奇怪的错误,我希望有人可以帮助我。 这是我创建视图控制器并将其推送到navigationController时的代码。 问题是将随机变量传递给新的视图控制器。我尝试在init方法中传递它,并使用下面注释的行传递它。

    MultipleBet *multipleBet = [[MultipleBet alloc] initWithMaxNumber:numbers andMaxStars:stars andRandom:self.random];
    NSLog(@"RANDOM1: %d", self.random);
    //[multipleBet setRandom:self.random];

    UIBarButtonItem *backButton = [[[UIBarButtonItem alloc] init] autorelease];
    backButton.title = @"Voltar";
    self.navigationItem.backBarButtonItem = backButton;
    [self.navigationController pushViewController:multipleBet animated:YES];

    [multipleBet release];

但是,当我在MultipleBet的viewDidLoad中访问随机变量时,它始终为FALSE。

这是MultipleBet的代码:

- (id)initWithMaxNumber:(int)maxNumbers andMaxStars:(int)maxStars andRandom:(BOOL)isRandom {
    self = [super initWithNibName:@"MultipleBet" bundle:[NSBundle mainBundle]];
    ...

    self.random = isRandom;
    NSLog(@"RANDOM2: %d", self.random);
    NSLog(@"RANDOM2.1: %d", isRandom);

return self;
}

这里是viewDidLoad的代码:

- (void)viewDidLoad {
   [super viewDidLoad];


    NSLog(@"RANDOM2.2: %d", self.random);

}

我声明变量和属性如下:

BOOL random;
@property (nonatomic) BOOL random;

并且输出始终为:
RANDOM2.2:0
随机2:1
RANDOM2.1:1
随机1:1

为什么viewDidLoad中的NSLog会在所有其他之前输出?它应该是最后一个......可能是因为我的自定义init方法?我打电话给[super init],所以它应该不是问题...

3 个答案:

答案 0 :(得分:21)

viewDidLoadinit*方法无法保证一个接一个地执行。 init*方法中的代码可能导致视图加载,因此即使viewDidLoad方法尚未完成,也会调用init*

很可能,您省略的部分中的某些代码会导致视图加载。如果您将向我们展示这一部分,也许我们可以指出它。或者,您也可以将self.random = isRandom;行移动到if (self)块中的第一行,看看是否有效。这样,在您分配self.random后,将执行导致视图加载的任何内容。

- (id)initWithMaxNumber:(int)maxNumbers andMaxStars:(int)maxStars andRandom:(BOOL)isRandom {
    self = [super initWithNibName:@"MultipleBet" bundle:[NSBundle mainBundle]];
    if (self) {
        // do this first
        self.random = isRandom;
        NSLog(@"RANDOM2: %d", self.random);
        NSLog(@"RANDOM2.1: %d", isRandom);

        // do the other code after
        ...
    }

    return self;
}

答案 1 :(得分:2)

我碰到了这个问题。我在选择器中调用了一个带有self的方法或属性,例如init *方法中的self.bannerView.frame或[self createBannerView]。 显然,self还没有在那时完成初始化,所以显然Apple有一些代码会在访问属性或方法之前调用viewDidLoad。 我的解决方案是将调用移出init并将它们放在viewDidLoad中。

答案 2 :(得分:0)

可能在您遗漏的部分(...)中,您导致视图以某种方式加载。即,在初始化程序中调用setter可能会导致您执行[self.tableView reloadData]或其他操作。