1

如果这是转发,我很抱歉,但我一直在网上搜索,似乎找不到任何有用的东西。我有一个锻炼列表,我显示在一个表格视图中,这些锻炼收集在捆绑包中的 plist 中。我还有一个单独的选项卡,允许用户构建自己的锻炼并将它们保存在文档文件夹 plist 文件中。一旦它们被保存,它们就会被添加到表格视图中。在模拟器中,everyuhting 工作正常。但是在实际设备上,除非我长时间关闭程序,从xcode重新加载程序或关闭手机,否则它不会更新。我尝试将 [[self tableview] reload] 添加到“viewDidLoad”、“viewWillappear”和“viewDidAppear”,但它们都不起作用。再一次,文件被保存,更新确实在模拟器中工作,但它没有 t 立即在手机中更新。有什么建议么?谢谢。

编辑:我知道这是一段很长的代码,但应该直截了当(希望大声笑)

#import "BIDWODList.h"
#import "BIDWODDetails.h"

#define kFileName   @"SavedDFWorkouts.plist"

@interface BIDWODList ()

@end

@implementation BIDWODList
@synthesize names;
@synthesize savedNames;
@synthesize keys;
@synthesize details;
@synthesize wodType;
@synthesize benchmarkGirls;
@synthesize theNewGirls;    
@synthesize heroes;
@synthesize savedDFGWorkouts;
@synthesize chosenWOD;
@synthesize chosenDetails;

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSMutableArray *buildBenchmarkGirls = [[NSMutableArray alloc] init];
    NSMutableArray *buildTheNewGirls = [[NSMutableArray alloc] init];
    NSMutableArray *buildHeroes = [[NSMutableArray alloc] init];

    NSBundle *bundle = [NSBundle mainBundle];
    NSURL *plistURL = [bundle URLForResource:@"CrossfitWOD" withExtension:@"plist"];
    //put the contents of the plist into a NSDictionary, and then into names instance variable
    NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfURL:plistURL];
    self.names = dictionary;
    //take all the keys in the dictionary and make an array out of those key names
    self.keys = [self.names allKeys];

    for (NSString *nameCheck in keys){
        self.details = [names valueForKey:nameCheck];
        if ([[self.details valueForKey:@"Type"] isEqualToString:@"The Benchmark Girls"]) {
            [buildBenchmarkGirls addObject:nameCheck];
        }else if ([[self.details valueForKey:@"Type"] isEqualToString:@"The New Girls"]) {
            [buildTheNewGirls addObject:nameCheck];
        }else {
            [buildHeroes addObject:nameCheck];
        }
    }

    NSString *filePath = [self dataFilePath];
    NSMutableDictionary *savedWorkout = [[NSMutableDictionary         alloc]initWithContentsOfFile:filePath];
    self.savedNames = savedWorkout;
    self.savedDFGWorkouts = [[savedWorkout allKeys]     sortedArrayUsingSelector:@selector(compare:)];

    self.benchmarkGirls = [buildBenchmarkGirls sortedArrayUsingSelector:@selector(compare:)];
    self.theNewGirls = [buildTheNewGirls sortedArrayUsingSelector:@selector(compare:)];
    self.heroes = [buildHeroes sortedArrayUsingSelector:@selector(compare:)];
//[[self tableView] reloadData];  //reloads the data in case a DFG workout was saved

}

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.names = nil;
    self.keys = nil;
    self.benchmarkGirls = nil;
    self.theNewGirls = nil;;
    self.heroes = nil;
    self.details = nil;

}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (NSString *)dataFilePath {
    NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:kFileName];
}

-(void)viewDidAppear:(BOOL)animated{
    [[self tableView] reloadData];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 4;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    if (section == 0) {
        return [benchmarkGirls count];
    }else if (section == 1){
        return [theNewGirls count];
    }else if (section == 2){
        return [heroes count];
    }else{
        return [savedDFGWorkouts count];
    }

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger section = [indexPath section];
    NSUInteger row = [indexPath row];

    static NSString *SectionsTableIdentifier = @"SectionsTableIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SectionsTableIdentifier];
    }

    if (section == 0) {
        cell.textLabel.text = [benchmarkGirls objectAtIndex:row];
    }else if (section == 1) {
        cell.textLabel.text = [theNewGirls objectAtIndex:row];
    }else if (section == 2) {
        cell.textLabel.text = [heroes objectAtIndex:row];
    }else{
        cell.textLabel.text = [savedDFGWorkouts objectAtIndex:row];
    }
    return cell;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    if (section == 0) {
        return @" The Benchmark Girls";
    }else if (section == 1){
        return @"The New Girls";
    }else if (section ==2){
        return @"The Heroes";
    }else{
        return @"Saved DFG Workouts";
    }
}



#pragma mark - Table view delegate


- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    BIDWODDetails *destination = segue.destinationViewController;

NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
if (section == 0) {
    self.chosenWOD = [self.benchmarkGirls objectAtIndex:row];
    self.chosenDetails = [names objectForKey:chosenWOD];
}else if (section == 1) {
    self.chosenWOD = [self.theNewGirls objectAtIndex:row];
    self.chosenDetails = [names objectForKey:chosenWOD];
}else if (section ==2) {
    self.chosenWOD = [self.heroes objectAtIndex:row];
    self.chosenDetails = [names objectForKey:chosenWOD];
}else {
    self.chosenWOD = [self.savedDFGWorkouts objectAtIndex:row];
    self.chosenDetails = [savedNames objectForKey:chosenWOD];
}//end if

//self.chosenDetails = [names objectForKey:chosenWOD];
//[destination setValue:chosenWOD forKey:@"chosenWOD"];
//[destination setValue:chosenDetails forKey:@"chosenDetails"];
destination.chosenWOD = self.chosenWOD;
destination.chosenDetails = self.chosenDetails;
}

@end
4

3 回答 3

2

模拟器和设备之间的不同行为通常与文件名中使用的不正确大小写有关 - 模拟器不区分大小写,而设备是。检查是否在引用 plist 文件的任何地方都使用了正确的大小写。

或者,在模拟器上,您可以直接写入应用程序包,但在设备上这是不可能的,您只能写入应用程序沙箱中的某些目录,通常是文档目录。您通常会在第一次运行时将 plist 复制到文档目录,然后使用该文件。

于 2012-08-26T06:05:53.237 回答
1

If I understand right your code you load plist file only in viewDidLoad, but most likely this function called only when you first time load your view. To make it work you should load plist in viewDidAppear. Something like this:

- (void)viewDidAppear {
  NSBundle *bundle = [NSBundle mainBundle];
  NSURL *plistURL = [bundle URLForResource:@"CrossfitWOD" withExtension:@"plist"];
//put the contents of the plist into a NSDictionary, and then into names instance variable
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfURL:plistURL];
self.names = dictionary;
//take all the keys in the dictionary and make an array out of those key names
self.keys = [self.names allKeys];

for (NSString *nameCheck in keys){
    self.details = [names valueForKey:nameCheck];
    if ([[self.details valueForKey:@"Type"] isEqualToString:@"The Benchmark Girls"]) {
        [buildBenchmarkGirls addObject:nameCheck];
    }else if ([[self.details valueForKey:@"Type"] isEqualToString:@"The New Girls"]) {
        [buildTheNewGirls addObject:nameCheck];
    }else {
        [buildHeroes addObject:nameCheck];
    }
}

NSString *filePath = [self dataFilePath];
NSMutableDictionary *savedWorkout = [[NSMutableDictionary         alloc]initWithContentsOfFile:filePath];
self.savedNames = savedWorkout;
self.savedDFGWorkouts = [[savedWorkout allKeys]     sortedArrayUsingSelector:@selector(compare:)];

 [self.tableView reloadData];

}
于 2012-08-27T15:30:22.210 回答
0

If it works in the Simulator and does not on the phone, almost for sure the problem is a timing issue. Saving files on a real phone takes much longer than on the simulator.

You should do the following:

  • when you save a file, log it, and log the return code from the save. If the way you save does not provide a return code, use NSFileManager to verify the file is in fact where it should be and even the size of it. This takes time to do but you should do it.

  • when your table is asking for the number of this and that, log it, and lot what is returned. You may find that that this comes before the files are saved.

It takes time and effort, but if you start logging all relevant things, you can find it. I just spend 6 hours today tracking down a race condition I had thought could never happen, and it was only after looking at a huge trail of messages that I was able to see the problem.

Almost for sure you will see that either file is not saved, its not where you thought it was, or that the phone timing means some events happen later than they do in the Simulator.

于 2012-08-27T22:58:33.010 回答