从UITableView委托方法中访问实例变量时获取“EXC_BAD_ACCESS”

时间:2009-09-20 02:07:26

标签: iphone uitableview delegates exc-bad-access

当我的iPhone应用程序从其中一个UITableView委托方法中访问实例变量时,它会爆炸。我想我保留它所以我不明白为什么我没有问题就无法访问它。

这是我的.h文件

#import <Foundation/Foundation.h>
#import "AlertSummaryCell.h"
#import "AlertDetailViewController.h"

@interface AlertSummaryTableViewController : UITableViewController {
NSDictionary *alerts;
NSString *alertKind;
}

@property(nonatomic,retain)NSDictionary *警告;    @property(nonatomic,retain)NSString * alertKind;

@end

在我的.m中,应用程序在第一次NSLog调用时终止:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(@"AlertSummaryTableViewController.numberOfRowsInSection entered");
NSLog(@"  alerts description = %@", [alerts description]);
// To know how many alert summaries we have, get the value for count out of the input dictionary
int theCount = [[alerts objectForKey:@"count"] intValue];
NSLog(@"  Going to return %d",theCount);
return theCount;
}

我缺少什么?

viewDidLoad方法完全没有问题:

 - (void)viewDidLoad {
 NSLog(@"AlertSummaryTableViewController.viewDidLoad entered");
 NSLog(@"  alerts description = %@", [alerts description]);

 // We want the View title to include the alert count
 // To know how many alert summaries we have, get the value for count out of the input dictionary
 int theCount = [[alerts objectForKey:@"count"] intValue];

 // Now construct the title text and set our views title to it
 NSString *myTitle = [[NSString alloc] initWithFormat:@"%@ Alerts (%d)",alertKind,theCount];
 [self setTitle: myTitle];

 // Memory cleanup
 [myTitle release];

 [super viewDidLoad];
 }

3 个答案:

答案 0 :(得分:4)

对于任何EXC_BAD_ACCESS错误,您通常会尝试向已发布的对象发送消息。跟踪这些内容的 BEST 方式是使用NSZombieEnabled

这可以通过永远不会实际释放一个对象,但将其包装为“僵尸”并在其中设置一个标志,表示它通常会被释放。这样,如果您再次尝试访问它,它仍然知道在发生错误之前它是什么,并且通过这些信息,您通常可以回溯以查看问题所在。

当调试器有时会抓取任何有用的信息时,它特别有助于后台线程。

非常重要注意但是,您需要100%确保这只是在您的调试代码而不是您的分发代码中。因为什么都没有发布,你的应用程序将泄漏,泄漏和泄漏。为了提醒我这样做,我把这个日志放在我的appdelegate:

if(getenv("NSZombieEnabled") || getenv("NSAutoreleaseFreedObjectCheckEnabled"))
  NSLog(@"NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled enabled!");

答案 1 :(得分:0)

我假设你已经检查过设置了警报。如果您尝试在nil引用上调用[alerts objectForKey:],则会出现该错误。

答案 2 :(得分:0)

问题原来是我设置警报的方式。而不是使用保留对象的setter方法,我无知地做了这个:

alerts = [[UIDictionary alloc] init];     // or something like this

编译没有任何警告或错误,我应该猜测。

使用setter,

[self setAlerts:[[UIDictionary alloc] init];   // again I'm going from memory so ...

我必须创建警报,因为它需要“保留”,一旦视图控制器加载,一切都很好。

我对Objective-C很新,不得不搞乱内存管理,但是在使用它和iPhone SDK大约4周后,我终于开始看到它了。