我有一个自定义类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访问它。
如何防止此变为零?
答案 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)
您的评论(您发布的答案是不应该做的)表明您在两个不同的实例上工作。
以下是几个可能的原因:
self.bvc
只是assign
属性而不是retain
。self.bvc
到nil
,以便您不断创建新的
实例