【问题标题】:Why is my instance variable nil even though I'm setting it?为什么我的实例变量为零,即使我正在设置它?
【发布时间】:2011-09-20 16:00:08
【问题描述】:

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

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

这是我创建 BoardViewController 的 sn-p,设置它的委托,然后设置新的 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 声明作为我试图找到这个错误的一部分。最初我有:

@synthesize boardMatchData;

...我刚刚切换回。行为是一样的; self.boardMatchData 总是以 nil 结束,即使在我设置之后也是如此。

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

如何防止它变成 nil?

【问题讨论】:

    标签: iphone ios


    【解决方案1】:
    @synthesize boardMatchData = _boardMatchData;
    

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

    【讨论】:

      【解决方案2】:

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

      这里有几个可能的原因:

      1. self.bvc 只是 assign 属性,而不是 retain
      2. 您从 nib 中加载一个,然后在您的代码中构建一个 (如图所示) - 这可能是最像的一个。也许你只是 忘记给插座接线了。
      3. 您在某处将self.bvc 设置为nil,以便您不断创建新的 实例。

      【讨论】:

        【解决方案3】:

        啊哈;我发现这个问题有一个几乎相同的问题:

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

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

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

        我还不确定如何或为什么,但这显然是问题所在(我设置了 boardMatchData 后正在实例化我的类的一个新实例)。

        编辑:

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

        我实际上是在 Xcode4 中使用故事板,Apple 提供了带有 Core Data 的主从模板。

        当我实例化我的细节控制器 (BoardViewController) 时,我正在执行分配/初始化。我应该只是引用 [segue destinationViewController],因为 segue 已经为我实例化了一个版本。 我没有提供足够的上下文来真正找到根

        【讨论】:

          猜你喜欢
          • 2020-11-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-13
          • 2016-04-09
          • 2015-04-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多