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

问题描述:

我有一个自定义类BoardMatchData,其中包含关于国际象棋比赛的信息。为什么我的实例变量零,即使我设置它?

我还得到了一个名为BoardViewController的自定义UIViewController,当用户从列表中选择一个匹配项时就会分配这个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。

编辑:

迦勒 - 我这样做,@synthesize声明作为我摆摆手周围的部分试图找到这个bug。原来我有:

@synthesize boardMatchData;

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

我想现在我只有一个伊娃,boardMatchData,我总是通过self.boardMatchData访问它。

我该如何防止它成为零?

@synthesize boardMatchData = _boardMatchData; 

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

Aha;我发现这个问题,有几乎相同的问题:

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

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

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

我不知道如何或为什么,但这显然是问题(我已经设置boardMatchData后,我的类的新实例正在实例化)。

编辑:

虽然上面使我发现这个错误(我得到我BoardViewController的多个版本)的路径,它不是完整的答案。我想在这里添加任何人都应该找到并且处于相同的位置。

我实际上是在Xcode4中使用故事板,并且Apple提供了Core Data的master-detail模板。

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

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

这里有几个可能的原因:

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