UITableViewController中的EXC_BAD_ACCESS

时间:2009-04-03 08:07:36

标签: iphone objective-c cocoa-touch

我正在尝试使用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个对象”,因此我认为这与问题有关。

8 个答案:

答案 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]); 之前没有出现此行,但似乎它减慢了我的调试速度。 ;)可悲的是,我现在无法重现真正的问题。

我可以说:错误是时间问题的结果。我现在仔细检查过这个。