编辑:使用嵌套数组并通过索引访问,到目前为止我有这个:
int currentHole = [holeLabel.text intValue];
holes = [[NSMutableArray alloc] init];
players = [[NSMutableArray alloc] init];
[holes addObject:players];
for (int i=0; i<=5; i++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow: i inSection: 0];
UITableViewCell *cell = [table cellForRowAtIndexPath:indexPath];
for (UIView *view in cell.contentView.subviews){
if ([view isKindOfClass:[UITextField class]]){
UITextField* txtField = (UITextField *)view;
if (txtField.tag == 6) {
int playerOneValue = [txtField.text intValue];
NSNumber *oneNumber = [NSNumber numberWithInteger:playerOneValue];
[players insertObject:oneNumber atIndex:0];
}
}
}
}
我有一个迷你高尔夫计分应用程序,它有一个表格视图,可以在向左或向右滑动(最多18个孔)时更改孔号。我想从每个用户的文本字段中保存笔画(最多六个),当用户滑回某个洞时,我想要检索保存到相应孔的字典中的笔画值(例如,针对第4洞的Dict 4)。最有效的方法是什么?
在用户向后滑动时调用的方法中我有:
//Array containing the strokes for the hole
holes = [[NSMutableArray alloc] init];
for (int i=0; i<=5; i++) {
// Go through each text field (with strokes) for the six players
NSIndexPath *indexPath = [NSIndexPath indexPathForRow: i inSection: 0];
UITableViewCell *cell = [table cellForRowAtIndexPath:indexPath];
for (UIView *view in cell.contentView.subviews){
if ([view isKindOfClass:[UITextField class]]){
UITextField* txtField = (UITextField *)view;
if (txtField.tag == 6) {
// Add the stroke status for each player to the holes array (then written to plist)
[holes addObject:txtField.text];
txtField.text = @"";
}
if (txtField.tag == 7) {
[holes addObject:txtField.text];
txtField.text = @"";
}
if (txtField.tag == 8) {
[holes addObject:txtField.text];
txtField.text = @"";
}
if (txtField.tag == 9) {
[holes addObject:txtField.text];
txtField.text = @"";
}
if (txtField.tag == 10) {
[holes addObject:txtField.text];
txtField.text = @"";
}
if (txtField.tag == 11) {
[holes addObject:txtField.text];
txtField.text = @"";
}
}
}
}
//String unique to each hole (e.g. Hole 12)
NSString *holeName = [NSString stringWithFormat:@"Hole %@", holeLabel.text];
// create dictionary with values in UITextFields
NSDictionary *plistDict = [NSDictionary dictionaryWithObjects: [NSArray arrayWithObjects:holes, nil]
forKeys:[NSArray arrayWithObjects: holeName, nil]];
NSString *error = nil;
// create NSData from dictionary
NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:plistDict format:NSPropertyListXMLFormat_v1_0
errorDescription:&error];
// check is plistData exists
if(plistData)
{
// write plist date to plist file
[plistData writeToFile:plistPath atomically:YES];
NSLog(@"plist written");
}
else
{
NSLog(@"Error in saveData: %@", error);
}
从plist文件中访问数据 - 获取plist dict中的数组以从当前孔访问:
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
// get documents path
NSString *documentsPath = [paths objectAtIndex:0];
// get the path to our Data/plist file
NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"Scores List.plist"];
// check to see if Scores List.plist exists in documents
if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath])
{
// if not in documents, get property list from main bundle
plistPath = [[NSBundle mainBundle] pathForResource:@"Scores List" ofType:@"plist"];
}
//Get hole string to search array from
NSString *holeString = [NSString stringWithFormat:@"Hole %@", holeLabel.text];
// read property list into memory as an NSData object
NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
NSString *errorDesc = nil;
NSPropertyListFormat format;
// convert static property liost into dictionary object
NSDictionary *temp = (NSDictionary *)[NSPropertyListSerialization propertyListFromData:plistXML
mutabilityOption:NSPropertyListMutableContainersAndLeaves
format:&format errorDescription:&errorDesc];
if (!temp)
{
NSLog(@"Error reading plist: %@, format: %lu", errorDesc, format);
}
holes = [NSMutableArray arrayWithArray:[temp objectForKey:holeString]];
NSLog(@"plist read");
for (int i=0; i<=5; i++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow: i inSection: 0];
UITableViewCell *cell = [table cellForRowAtIndexPath:indexPath];
for (UIView *view in cell.contentView.subviews){
if ([view isKindOfClass:[UITextField class]]){
UITextField* txtField = (UITextField *)view;
if (txtField.tag == 6) {
//Write the plist strokes integers to the strokes text boxes for each player
txtField.text = [holes objectAtIndex:0];
}
if (txtField.tag == 7) {
txtField.text = [holes objectAtIndex:1];
}
if (txtField.tag == 8) {
txtField.text = [holes objectAtIndex:2];
}
if (txtField.tag == 9) {
txtField.text = [holes objectAtIndex:3];
}
if (txtField.tag == 10) {
txtField.text = [holes objectAtIndex:4];
}
if (txtField.tag == 11) {
txtField.text = [holes objectAtIndex:5];
}
}
}
}
此代码适用于在向后滑动孔时检索上一个孔的笔划,但如果再次向后滑动,应用程序会崩溃,并显示错误,指出该数组为空且无法访问索引1处的值。我是确定除了plist之外,还有一种比我需要做的更好的方法。
答案 0 :(得分:1)
而不是作为字典的plist文件,你应该只使用数组。创建一个包含18个对象的数组。这些物体代表18个洞。只需使用索引(您想要观察的洞)访问这些对象,而不是创建密钥。
现在,数组中的每个对象也是一个表示玩家数量的数组。数组的索引代表播放器。
将实例变量创建为NSMutableArray类型的孔。 以下面的方式初始化。
holes = [[NSMutableArray alloc]init];
for(int hole = 0; hole < TOTAL_HOLES; hole++)
{
NSMutableArray *persons = [[NSMutableArray alloc]init];
for(int player = 0; player < TOTAL_PLAYERS; player++)
{
NSNumber *score = [NSNumber numberWithInt:-1];
[persons addObject:score];
}
[holes addObject:persons];
}
现在,阵列孔的每个对象代表该特定洞的每个玩家的得分。初始值设置为-1,这意味着尚未输入该特定洞的玩家得分。如果你想修改任何特定球员的得分,你可以通过以下方式进行。
NSNumber *score = [NSNumber numberWithInt:SCORE_OF_PLAYER];
NSMutableArray *scoresForHole = [holes objectAtIndex:SCORE_OF_PLAYER_FOR_HOLE];
[scoresForHole replaceObjectAtIndex:PLAYER_NUMBER withObject:score];
[holes replaceObjectAtIndex:3 withObject:scoresForHole];
因此,整体结构将成为,
[0] = {0,1,2,3... total players},
[1] = {0,1,2,3... total players},
.
.
.
[17] = {0,1,2,3... total players}
现在,当您想要访问第8号洞的玩家5记录时,您可以执行以下操作,
[[holes objectAtIndex:holeNum] objectAtIndex:playerNum];
要将数组写入文件并从文件初始化数组,可以使用数组类的库例程。希望能够简化您的问题。