2012-02-12 38 views
1

我一直在試圖解決這個不良參考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不保留參考TasksPageViewControllerUITableView找不到它的dataSource。我真的不知道如何使用ARC來保留這一點。

+0

我也注意到,當我嘗試滾動我收到相同_type_'的followig錯誤2012-02-12 21實現代碼如下:31:04.463 Pontinhos [46496:FE03] *** - [TasksPageViewController tableView:cellForRowAtIndexPath:]:發送到釋放實例0x6abd4b0的消息' – jturolla 2012-02-12 23:33:06

回答

0

在您的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++; 

} 
+0

謝謝jonkroll。我嘗試了你的修復,但它沒有改變。直到我在TasksPageViewController中插入tableview爲止,代碼的那部分工作正常。生成視圖的循環確實發生,因爲我可以在NSLog中看到它,但它在之後崩潰。 – jturolla 2012-02-12 23:00:12