我正在尝试使用UITableViewController(视图的委托和数据源)来显示从Plist读取的简单表。 Plist包含一个NSDictionary,它本身包含几个NSDictionary对象,这些对象表示我的应用程序中使用的对象。
代码的其余部分看起来像这样(简化):
- (void)viewDidLoad {
[super viewDidLoad];
[self loadObjectsFromPlist];
}
- (void)loadObjectsFromPlist {
NSString *objectPlistFile = [[NSBundle mainBundle] pathForResource:@"Objects" ofType:@"plist"];
NSDictionary *objectsDictionary = [NSDictionary dictionaryWithContentsOfFile:objectsPlistFile];
objects = [[NSMutableArray alloc] init];
NSEnumerator *objectEnumerator = [objectsDictionary objectEnumerator];
NSDictionary *objectData;
while(objectData = [objectEnumerator nextObject]) {
[objects addObject:[MyObject objectFromDictionary:objectData]];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [objects count];
}
由于我没有使用任何部分,因此我会在控制器的1
中返回numberOfSectionsInTableView
。
“objectFromDictionary
”的MyObject
方法将从NSDictionary
读取的数据分配给新对象。我也尝试过保留,复制等,但这并没有改变任何东西。
在致电EXC_BAD_ACCESS
时,我在tableView:numberOfRowsInSection
获得了[objects count]
。我尝试使用对象分配工具,但我没有发现问题。我的Plist目前仅包含一个对象的数据。调试器为objects
属性显示红色的“1个对象”,因此我认为这与问题有关。
答案 0 :(得分:2)
要确保在适当的时间加载数据,请尝试延迟初始化:
- (NSArray *)objectsFromPlist {
if (!objects) {
... // initialize once here
}
return objects;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[self objectsFromPlist] count];
}
答案 1 :(得分:1)
如果调试器显示EXC_BAD_ACCESS
发生在[servers count]
,(假设)ivar servers
是否正确初始化?我在示例代码中没有找到任何引用。
答案 2 :(得分:1)
什么是objects
?你能展示你的头文件吗?它可能会让我更好地理解。另外,您是否尝试在[super viewDidLoad]
之后添加[self loadObjectsFromPlist]
?这似乎是一个时间问题,或者objects
在您的某个方法中意外发布。
答案 3 :(得分:1)
我的猜测是你可能需要发布你的整个(相关)代码,而不是一个精简版本。在不知道你可能在做什么的情况下,无论是在代码还是在plist中,都很难确定这一点......我们都只是在这里盲目地开火(不可否认,在SO上并不常见; - )
答案 4 :(得分:0)
听起来它在调用loadObjectsFromPlist之前调用numberOfRowsInSection。
如果以编程方式加载控制器,可以尝试从initWithFrame调用loadObjectsFromPlist:Style:而不是viewDidLoad。
如果我面前有一台Mac,我会自己做,但你可能想尝试设置断点并弄清楚这些方法的调用顺序。整个地方的NSLog语句也有效。
答案 5 :(得分:0)
您可能已取消分配UITableViewController
,这意味着objects
成员不再有效。确保您在某个地方持有对UITableViewController
的引用。检查是否是这种情况的简单方法是在[self retain]
方法中添加viewDidLoad
来电(暂时!)。如果这样会导致问题消失,那么您需要仔细检查谁拥有控制器,并确保他们没有释放它。
编辑:我想更好的测试方法是在你的dealloc方法中加一个断点。
答案 6 :(得分:0)
将[self loadObjectsFromPlist]放在[super viewDidLoad]之前。 您的“对象”变量永远不会被初始化,这就是您收到EXEC_BAD_ACCESS错误的原因。
答案 7 :(得分:0)
好的,在阅读完所有答案并试图找到我的错误之后,我几乎完全重写了我的代码。 最后,我删除了第一次发生错误时添加的调试输出。
NSLog(@"Object count: %@", [objects count]);
由于NSArray
的{{1}}不会返回一个对象而是一个整数,这显然是错误的,应该是:
count
然而NSLog(@"Object count: %u", [objects count]);
之前没有出现此行,但似乎它减慢了我的调试速度。 ;)可悲的是,我现在无法重现真正的问题。
我可以说:错误不是时间问题的结果。我现在仔细检查过这个。