2012-02-12 4 views
1

私はこの悪い参照を2日間解決しようとしていましたが、修正が見つかりません。テーブルビューの「EXEC_BAD_ACCESS」、「[TasksPageViewController tableView:numberOfRowsInSection:]」

私のアプリケーションは、さまざまなカテゴリの複数のページ(UIPageControl)と、ユーザーが完了したタスクに関する統計の最初のページを持つ基本的なToDoリストです。 (もしあなたが3つのカテゴリを持っていれば、4ページになります)。

NSUserDefaultsからカテゴリの配列をロードします。これは、wheatherアプリケーションの(i)と同様にUIButtonでアクセスするモーダルビューで変更できます。

ページコントロールは、ViewControllerクラス(プライマリビュー)によって作成されます。カテゴリの配列内の各要素について、ビューコントローラは新しいTasksPageViewControllerクラスインスタンスを生成し、それに対するストーリーボードビューをインスタンス化します。

ストーリーボードのTasksPageViewControllerビューにUITableViewを入れ、そのデータソースを同じクラスにリンクするまでは、すべて正常に機能していました。

TasksPageViewControllerのUITableView dataSourceに必要なクラスを実装した後は正常に動作しますが、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; 
} 

ありがとうございます。

EDIT:明らかにViewControllerTasksPageViewControllerへの参照を保持せず、UITableViewはそのデータソースを見つけることができません。 ARCを使用してこれを保持する方法はわかりません。

+0

私も2012-02-12 '私はテーブルビューをスクロールしようとすると、私は同じ_type_のfollowigエラーを受け取ることに注意してください可能性が21:31:04.463 Pontinhos [46496:FE03] *** - [TasksPageViewController tableView:cellForRowAtIndexPath:]:割り当て解除されたインスタンスに送信されたメッセージ0x6abd4b0' – jturolla

答えて

0

012ContractController viewDidLoadで、カテゴリをループすると、tasksという名前のTasksPageViewControllerがインスタンス化されますが、参照はどこにも保持されません。だから、tableView:numberOfRowsInSection:メッセージが送信されたときにTasksPageViewControllerが見つかりません。

あなたのViewControllerにはviewsという名前のプロパティが合成されていますが、そのプロパティはどこでも使用されません。おそらく、そのプロパティの名前をviewControllersに変更し、ループの最後にviewDidLoadを追加する場合は、tasksをnilに設定するのではなく、viewControllers可変配列にtasksオブジェクトを追加する必要があります。私はそれがクラッシュを防ぐかもしれないと思います。

for(id name in categories) { 

    TasksPageViewController *tasks = [self.storyboard instantiateViewControllerWithIdentifier:@"TasksPageViewController"]; 

    ... 

    [scrollView addSubview:tasks.view]; 
    [self.viewControllers addObject:tasks]; 
    i++; 

} 
+0

ありがとうございましたjonkroll。私はあなたの修正を試みたが、それは変更を加えなかった。私がTaskviewPageViewControllerにtableviewを挿入するまで、コードのその部分はうまくいきました。私はNSLogで見ることができるように、ビューを生成するループが発生しますが、直後にクラッシュします。 – jturolla

関連する問題