'EXEC_BAD_ACCESS'在表视图中,“[TasksPageViewController tableView:numberOfRowsInSection:]”
我一直在试图解决这个不良参考2天,但我找不到修复程序。'EXEC_BAD_ACCESS'在表视图中,“[TasksPageViewController tableView:numberOfRowsInSection:]”
我的应用程序是一个基本的待办事项列表,包含不同类别的多个页面(UIPageControl)以及关于用户完成的任务的统计信息的第一页。 (如果您有3个类别,则最终有4个页面)。
它从NSUserDefaults加载一个类别数组,它可以通过UIButton访问的模式视图进行修改,就像在wheather应用程序中的(i)一样。
Page Control由ViewController
类构建(这是主视图)。对于类别数组中的每个元素,视图控制器会生成一个新的TasksPageViewController
类实例并为其实例化一个故事板视图。
一切工作正常,直到我把故事板TasksPageViewController
视图UITableView
并将其dataSource链接到同一类。
在TasksPageViewController
中为UITableView数据源实现所需的类后,它运行良好,但是如果我尝试进入修改类别的模式视图时,按DONE(并且它应该重新加载ViewController并重建UIPageControll的许多页面),该应用程序崩溃与EXEC_BAD_ACCESS。
调试与NSZombiesEnabled,我得到:
2012-02-12 18:55:49.460 Pontinhos [25601:FE03] * - [TasksPageViewController的tableView:numberOfRowsInSection:]:消息发送到释放实例0x68c3040
但我真的不知道如何继续,我不知道哪个对象被释放,我打电话。
脚本如下:
ViewController.h
#import <UIKit/UIKit.h>
#import "MainPageViewController.h"
#import "TasksPageViewController.h"
@interface ViewController : UIViewController{
IBOutlet UIScrollView *scrollView;
IBOutlet UIPageControl *pageControl;
NSMutableArray * views;
// To be used when scrolls originate from the UIPageControl
BOOL pageControlUsed;
}
@property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
@property (nonatomic, retain) IBOutlet UIPageControl *pageControl;
@property (nonatomic, retain) NSMutableArray *views;
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
- (IBAction)changePage;
@end
ViewController.m
#import "ViewController.h"
@implementation ViewController
@synthesize scrollView;
@synthesize pageControl;
@synthesize views;
//carrega views que estão na array.
- (void)viewDidLoad
{
[super viewDidLoad];
//LoadCategories
NSUserDefaults *data = [NSUserDefaults standardUserDefaults];
NSMutableArray *categories = [[NSMutableArray alloc] initWithArray:[data objectForKey:@"categories"]];
// MAIN PAGE
MainPageViewController *mainpage = [self.storyboard instantiateViewControllerWithIdentifier:@"MainPageViewController"];
CGRect mframe = scrollView.frame;
mframe.origin.x = 0;
mframe.origin.y = 0;
mainpage.view.frame = mframe;
[self.scrollView addSubview:mainpage.view];
int i = 1;
NSLog(@"Iniciando criação de páginas!");
for(id name in categories) {
NSLog(@"Carregou página.%i",i);
NSLog(@"categories count:%i",[categories count]);
TasksPageViewController *tasks = [self.storyboard instantiateViewControllerWithIdentifier:@"TasksPageViewController"];
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * i;
frame.origin.y = 0;
tasks.view.frame = frame;
[tasks populateWithData:(i-1) categoryName:name];
[scrollView addSubview:tasks.view];
tasks = nil;
i++;
}
self.pageControl.numberOfPages = [categories count]+1;
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * ([categories count]+1), self.scrollView.frame.size.height);
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (pageControlUsed)
{
// do nothing - the scroll was initiated from the page control, not the user dragging
return;
}
// Update the page when more than 50% of the previous/next page is visible
CGFloat pageWidth = self.scrollView.frame.size.width;
int page = floor((self.scrollView.contentOffset.x - pageWidth/2)/pageWidth) + 1;
self.pageControl.currentPage = page;
}
- (IBAction)changePage {
// update the scroll view to the appropriate page
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * self.pageControl.currentPage;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
[self.scrollView scrollRectToVisible:frame animated:YES];
pageControlUsed = YES;
}
// At the begin of scroll dragging, reset the boolean used when scrolls originate from the UIPageControl
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
pageControlUsed = NO;
}
// At the end of scroll animation, reset the boolean used when scrolls originate from the UIPageControl
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
pageControlUsed = NO;
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.scrollView = nil;
}
@end
TasksPageViewController.h
#import <UIKit/UIKit.h>
#import "TasksTableCellPrototypes.h"
@interface TasksPageViewController : UIViewController <UITableViewDataSource>{
IBOutlet UILabel *categoryName;
IBOutlet UITableView *tableView;
//NSMutableArray *tasksData;
}
//@property (nonatomic,retain) NSMutableArray *tasksData;
@property (nonatomic,retain) UITableView *tableView;
@property (nonatomic,retain) UILabel *categoryName;
- (void) populateWithData:(int)dataId categoryName:(NSString *)name;
@end
TasksPageViewControlle r.m
#import "TasksPageViewController.h"
@implementation TasksPageViewController
@synthesize tableView;
//@synthesize tasksData;
@synthesize categoryName;
- (void)viewDidLoad
{
[super viewDidLoad];
// NSUserDefaults *data = [NSUserDefaults standardUserDefaults];
//tasksData = [[NSMutableArray alloc] initWithArray:[data objectForKey:@"tasks"]];
//tasksData = [[NSMutableArray alloc] initWithObjects:@"lalal",@"lololo",nil];
}
- (void) populateWithData:(int)dataId categoryName:(NSString *)name {
//self.categoryName.text = name;
}
// Número de categorias
- (NSInteger)tableView:(UITableView *)tableViewnumberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSLog(@"contou table view tasks");
return 4;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
TasksTableCellPrototypes *cell = [[TasksTableCellPrototypes alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"taskCell"];
return cell;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
谢谢。
编辑:显然ViewController
不保留参考TasksPageViewController
和UITableView
找不到它的dataSource。我真的不知道如何使用ARC来保留这一点。
在您的ViewController viewDidLoad
中,当您循环访问类别时,您会实例化一个名为tasks
的TasksPageViewController,但您不会在任何地方保留引用。因此,稍后在发送tableView:numberOfRowsInSection:
消息时无法找到TasksPageViewController。
我看到在您的ViewController中,您综合了一个名为views
的属性,但是您不会在任何地方使用该属性。也许你应该重命名该属性viewControllers
,然后在viewDidLoad
循环结束时,您应该将tasks
对象添加到viewControllers
可变阵列中,而不是将tasks
设置为零。我认为这可能会防止崩溃。
for(id name in categories) {
TasksPageViewController *tasks = [self.storyboard instantiateViewControllerWithIdentifier:@"TasksPageViewController"];
...
[scrollView addSubview:tasks.view];
[self.viewControllers addObject:tasks];
i++;
}
谢谢jonkroll。我尝试了你的修复,但它没有改变。直到我在TasksPageViewController中插入tableview为止,代码的那部分工作正常。生成视图的循环确实发生,因为我可以在NSLog中看到它,但它在之后崩溃。 – jturolla 2012-02-12 23:00:12
我也注意到,当我尝试滚动我收到相同_type_'的followig错误2012-02-12 21实现代码如下:31:04.463 Pontinhos [46496:FE03] *** - [TasksPageViewController tableView:cellForRowAtIndexPath:]:发送到释放实例0x6abd4b0的消息' – jturolla 2012-02-12 23:33:06