为什么我的实例变量为零,即使我正在设置它?

时间:2011-09-20 16:00:08

标签: iphone ios

我有一个自定义类BoardMatchData,其中包含有关国际象棋比赛的信息。

我还有一个名为BoardViewController的自定义UIViewController,当用户从列表中选择一个匹配时,它会被分配。

这是我创建BoardViewController,设置其委托,然后设置新的BoardMatchData的片段:

    Games *selectedGame = [[self fetchedResultsController] objectAtIndexPath:indexPath];
    if (!self.bvc) {
        NSLog(@"Alloc-ing a BVC");
        self.bvc = [[BoardViewController alloc] init];
        self.bvc.delegate = self;
    }
    [self.bvc setNewBoardMatchData:[MasterViewController boardMatchDataFromGame:selectedGame]];

调试时,我可以看到调用此方法setNewBoardMatchData,并且它有有效的数据。但是,稍后在BoardViewController中,这个boardMatchData似乎总是为零。这是setNewBoardMatchData方法:

- (void)setNewBoardMatchData:(BoardMatchData *)newBoardMatchData {
    NSLog(@"BMD is being set");
    if (self.boardMatchData != newBoardMatchData) {
        self.boardMatchData = newBoardMatchData;
        [self configureView];
    }
    if (self.masterPopoverController != nil) {
        [self.masterPopoverController dismissPopoverAnimated:YES];
    }

}

在BoardViewController.h中,我只有一个实例变量:

BoardMatchData *boardMatchData;

方法声明:

- (void)setNewBoardMatchData:(BoardMatchData *)newBoardMatchData;

然后在BoardMatchData.m的顶部,我有:

@interface BoardViewController ()
@property (strong, nonatomic) UIPopoverController *masterPopoverController;
@property (nonatomic,retain) BoardMatchData *boardMatchData; 
- (void)configureView;
@end
  

@synthesize boardMatchData = _boardMatchData;

......我的目的是确保setter只能被自己调用,而不是被其他对象调用。

我是怎么设置self.boardMatchData的?

我没有做任何保留/发布,因为我正在使用ARC。

编辑:

Caleb - 我做了@synthesize声明,作为我试图找到这个bug的一部分。原来我有:

  

@synthesize boardMatchData;

...我刚刚切换回来。行为是一样的;即使在我设置之后,self.boardMatchData也总是为零。

我认为现在我只有一个ivar,boardMatchData,我总是通过self.boardMatchData访问它。

如何防止此变为零?

3 个答案:

答案 0 :(得分:2)

@synthesize boardMatchData = _boardMatchData;

这表示访问者应该使用的ivar是_boardMatchData,但你也有一个名为boardMatchData的ivar。如果您使用的是访问者,则只会设置_boardMatchData。由于Objective-C会在创建对象时自动清除任何ivars,因此boardMatchData ivar将始终为零。

答案 1 :(得分:0)

阿哈;我发现这个问题几乎完全相同:

Objective-C – Retained property after being set is nil?

那个没有结论,但最后的建议是“尝试在-viewDidLoad和-viewWillAppear和-queueFinished中记录self的地址。像NSLog(@”self is%p“,self);和确保它们是相同的。“

我自己做了,现在看到在initWithNibName / configureView / setNewBoardMatchData中,我看到一个自我指针,然后当viewDidLoad运行时,我得到另一个!

我不知道是怎么回事,为什么呢,但这显然是问题所在(我的类的一个新实例在我设置boardMatchData后被实例化)。

编辑:

虽然上面引导我找到这个bug的路径(我得到了我的BoardViewController的多个版本),但这不是完整的答案。如果有人发现这个并且处于相同的位置,我想在此添加。

我实际上是在Xcode4中使用故事板,Apple提供了核心数据的主要细节模板。

当我实例化我的细节控制器(BoardViewController)时,我正在做一个alloc / init。我应该简单地引用[segue destinationViewController],因为segue已经为我实例化了一个版本。 我没有提供足够的上下文来实际访问根

答案 2 :(得分:0)

您的评论(您发布的答案是不应该做的)表明您在两个不同的实例上工作。

以下是几个可能的原因:

  1. self.bvc只是assign属性而不是retain
  2. 您从笔尖中加载一个,并在您的代码中构建一个     (如图所示) - 这可能是最像一个。也许你就是     忘了给插座打电话。
  3. 您的设置self.bvcnil,以便您不断创建新的     实例