私はBOSSのプログラミングに関するBNRガイドを勉強しています。私がやっていることの要約はこれです。私はtableViewのセクションを管理する柔軟な方法が必要でした。したがって、セクションを保持するNSMutableArrayを構築しました。配列の各オブジェクトはNSDictionaryを介してテーブルセクションを表します。辞書には2つのキーがあり、セクションヘッダーの文字列とセクションの所有物を保持する配列があります。私はストアクラスからallPossesionsを取得し、適切な配列と辞書に並べ替えて保存する少しのルーチンを持っています。私はこれを組み込むために私のコードを書き直す作業をしてきました。そして私は混乱しているロードブロックを打ちました。私のアプリがデバッガで動くとき、何が起こっているかを追跡するためにNSLogをたくさん投げています。私はセクション・アレイの内容にアクセスしてログを記録するのに問題はないようです。あるいは、テーブル・ビューのサポート方法のほとんどがnsdictionariesです。しかし、cellForRowAtIndexpathが呼び出されると、コード神は私に笑いを止めます。どういうわけか私の所有物の配列にアクセスしたりログアウトしたりしようとすると、突然空になります。UITableViewデータソースの問題。私のデータ配列は突然空です。UITableView:cellForRowAtIndexPath:が呼び出されました。
私の人生にとってはこれを理解できません。私はこれで1日ちょっと頭を打っていて、どんなインプットや助けも喜んで受け入れるだろう。以下はitemsViewController.hと実装です。ログの混乱を見落とし、セクションをコメントアウトしてください。私はこれを理解しようとしてきたので、人々はこれに私のアプローチについて変更する必要があるかもしれないことを私に教えてくれるかもしれません。また、テーブルが最初は空であり、何かを追加しようとするまでアプリが何の問題もないことに注意する価値があります。ここで
//
// ItemsViewController.h
// HomePwnr
#import <Foundation/Foundation.h>
#import "ItemDetailViewController.h"
@interface ItemsViewController : UITableViewController
{
NSMutableArray *sections; // variable to hold the number of sections
}
-(void)addNewPossession:(id)sender;
-(void)divideSections;
@end
は、最後にここに実装
//
// ItemsViewController.m
// HomePwnr
#import "ItemsViewController.h"
#import "PossessionStore.h"
#import "Possession.h"
@implementation ItemsViewController
- (id) init
{
NSLog(@"ItemsViewController init called");
// Call the superclass's designated initializer
self = [super initWithStyle:UITableViewStyleGrouped];
if (self) {
// create a new barItem that will send addNePossession: to itemsViewController
UIBarButtonItem *bbi = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addNewPossession:)];
// Set this barButtonItem as the right item in the Navigation item
[[self navigationItem] setRightBarButtonItem:bbi];
//The Navigation item retains its buttons so release bbi
[bbi release];
// set the title of the navigation item
[[self navigationItem] setTitle:@"Homepwner"];
//[[self navigationItem] setLeftBarButtonItem:[self editButtonItem]];
}
sections = [[[NSMutableArray alloc] init] retain]; // added the extra retain here to make sure my sections weren't getting released pre maturely
// set up sections here by dividing allPossessions
[self divideSections];
return self;
}
- (id) initWithStyle:(UITableViewStyle)style
{
return [self init];
}
-(void)divideSections
{
NSLog(@"divideSections called");
// For simplicity we'll just empty out the sections array and rebuild it each time we add or modify a possesion
[sections removeAllObjects];
NSArray *cheapStuff = [[NSArray alloc] initWithArray:[[PossessionStore defaultStore] possesionsFromPredicate:@"valueInDollars < 50"]];
NSArray *expensiveStuff = [[NSArray alloc] initWithArray:[[PossessionStore defaultStore] possesionsFromPredicate:@"valueInDollars >= 50"]];
// we'll be making an NSDictionary for each section. it will hold an array of possesions for each section and it's key will serve as the sections header
if ([cheapStuff count] > 0) {
NSMutableDictionary *section1 = [NSMutableDictionary dictionaryWithObject:cheapStuff forKey:@"Possessions"];
[section1 setValue:@"Cheap Stuff" forKey:@"Header"];
[sections addObject:section1];
// sections now retains NSDictionary so we release it
[section1 release];
}
if ([expensiveStuff count] > 0) {
NSMutableDictionary *section2 = [NSMutableDictionary dictionaryWithObject:expensiveStuff forKey:@"Possessions"];
[section2 setValue:@"Cheap Stuff" forKey:@"Header"];
[sections addObject:section2];
// sections now retains NSDictionary so we release it
[section2 release];
}
//now our arrays are retained by the dictionarys so we release them
[cheapStuff release];
[expensiveStuff release];
NSLog(@" End of divideSections sections holding %@", sections);
}
/*
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ItemDetailViewController *detailViewController = [[[ItemDetailViewController alloc] init] autorelease];
// NSArray *possessions = [[PossessionStore defaultStore] allPossessions];
// give the detail view controller a pointer to the possesion object in row
// get the NSDictionary located at the section index, get the dictionary's array, get the possession at row index
Possession *p = [[[sections objectAtIndex:[indexPath section]] objectAtIndex:0] objectAtIndex:[indexPath row]];
[detailViewController setPossession:p];
// push it onto the navigationControllers stack
[[self navigationController] pushViewController:detailViewController animated:YES];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
////If the table view is asking to commit the delete command
if (editingStyle == UITableViewCellEditingStyleDelete) {
//PossessionStore *ps = [PossessionStore defaultStore];
// NSArray *possessions = [ps allPossessions];
// Possession *p = [possessions objectAtIndex:[indexPath row]];
int section = [indexPath section];
int row = [indexPath row];
Possession *p = [[[sections objectAtIndex:section] objectAtIndex:0] objectAtIndex:row];
[[[PossessionStore defaultStore] allPossessions] removePossession:p];
// remove the row from the table view with an animation
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
}
}
-(void) tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
[[PossessionStore defaultStore] movePossessionAtIndex:[sourceIndexPath row] toIndex:[destinationIndexPath row]];
}
*/
-(void)addNewPossession:(id)sender
{
//
NSLog(@"addNewPossession called - sections = %@", sections);
[[PossessionStore defaultStore] createPossession];
//NSLog(@"Possesion store now holds %@", [[PossessionStore defaultStore] allPossessions]);
//we've added a new possession so we'll divide out the sections again
[self divideSections];
//NSLog(@"addNewPossession exiting - sections = %@", sections);
//tableview returns the tablesview
[[self tableView] reloadData];
//NSLog(@"table view reloading data - sections = %@", sections);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int numSections = [[(NSArray *)[sections objectAtIndex:section] objectForKey:@"Possessions"] count];
//NSLog(@"numberOfRowsInSection: called for section %i, returning %i.", section, numSections);
return numSections;
}
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
NSLog(@"returning number of sections: %i", [sections count]);
// return the count of the sections array
return [sections count];
}
- (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSLog(@"tableView:titleForHeaderInSectionCalled - sections = %@", sections);
//Configure the header titles based on the number of sections
if ([sections count] <= 1) {
// return simple title for only one section in table
NSLog(@"Returning My Stuff");
return @"My Stuff";
} else {
NSLog(@"The header returned is %@", [[sections objectAtIndex:section] objectForKey:@"Header"]);
// or return the key for the dictionary entry for the current section
return [[[sections objectAtIndex:section] objectAtIndex:section] objectForKey:@"Header"];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"tableView:cellForRowAtIndexPath called for section %d, Row %d", [indexPath section], [indexPath row]);
NSLog(@"Sections = %@", sections);
NSLog(@"The Dictionary is %@", [sections objectAtIndex:[indexPath section]]);
//NSLog(@"thisSection array should be %@", (NSArray *)[[sections objectAtIndex:thisSection] objectForKey:@"Possessions"]);
//NSArray *thisSectionArray = [[sections objectAtIndex:thisSection] objectForKey:@"Possessions"];
// Check for reusable cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
// If there is no cell of this type create a new one
if (!cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"UITableViewCell"] autorelease];
}
// get the NSDictionary located at the section index, get the dictionary's array, get the possession at row index
//Possession *p = [thisSection objectAtIndex:[indexPath row]];
//[[cell textLabel] setText:[p description]];
[[cell textLabel] setText:@"cell text"];
return cell;
}
-(void)viewWillAppear:(BOOL)animated
{
[self divideSections];
[super viewWillAppear:YES];
NSLog(@"viewWillAppear called - sections = %@", sections);
}
-(void)viewDidUnload
{
[super viewDidUnload];
NSLog(@"viewDidUnload called - sections = %@", sections);
}
@end
は、アプリケーションを実行しようとしているから、私のログです。小さな緑色のインジケータは、アプリケーションのクラッシュ後にcellForRow .......の間にセクションの内容をログに記録しようとする行のすぐ上にあります。
2012-03-10 06:22:00.177 HomePwnr[44399:f803] ItemsViewController init called
2012-03-10 06:22:00.180 HomePwnr[44399:f803] divideSections called
2012-03-10 06:22:00.181 HomePwnr[44399:f803] End of divideSections sections holding (
)
2012-03-10 06:22:00.188 HomePwnr[44399:f803] divideSections called
2012-03-10 06:22:00.189 HomePwnr[44399:f803] End of divideSections sections holding (
)
2012-03-10 06:22:00.189 HomePwnr[44399:f803] returning number of sections: 0
2012-03-10 06:22:00.190 HomePwnr[44399:f803] returning number of sections: 0
2012-03-10 06:22:00.191 HomePwnr[44399:f803] viewWillAppear called - sections = (
)
2012-03-10 06:22:04.234 HomePwnr[44399:f803] addNewPossession called - sections = (
)
2012-03-10 06:22:04.235 HomePwnr[44399:f803] divideSections called
2012-03-10 06:22:04.237 HomePwnr[44399:f803] End of divideSections sections holding (
{
Header = "Cheap Stuff";
Possessions = (
"Shiny Gun (7R3K0): Worth $40, recorded on 2012-03-10 11:22:04 +0000"
);
}
)
2012-03-10 06:22:04.238 HomePwnr[44399:f803] returning number of sections: 1
2012-03-10 06:22:04.239 HomePwnr[44399:f803] tableView:titleForHeaderInSectionCalled - sections = (
{
Header = "Cheap Stuff";
Possessions = (
"Shiny Gun (7R3K0): Worth $40, recorded on 2012-03-10 11:22:04 +0000"
);
}
)
2012-03-10 06:22:04.240 HomePwnr[44399:f803] Returning My Stuff
2012-03-10 06:22:04.241 HomePwnr[44399:f803] tableView:titleForHeaderInSectionCalled - sections = (
{
Header = "Cheap Stuff";
Possessions = (
"Shiny Gun (7R3K0): Worth $40, recorded on 2012-03-10 11:22:04 +0000"
);
}
)
2012-03-10 06:22:04.241 HomePwnr[44399:f803] Returning My Stuff
2012-03-10 06:22:04.243 HomePwnr[44399:f803] tableView:cellForRowAtIndexPath called for section 0, Row 0
(lldb)
誰でもアドバイスをありますか? – vichudson1