1

我正在构建一个以 a 开头的应用程序,UITableView但是当我第一次在手机上构建和运行我的应用程序时,它UITableView显示为空。如果我停止运行,然后重新构建并再次运行它,所有数据都会显示出来。此外,如果该应用程序已经在我的手机上,它可以构建并运行良好。这只是第一个初始构建并在我的手机上“安装”应用程序时运行,它留下了UITableView空白。我很好奇这是否会在苹果审查我的应用程序时引起任何问题?为了实现这一点,我做错了什么吗?

注意:UITableView正在从正在移动到文档目录的 plist 中填充。我最初的想法是UITableView在 plist 成功移动到文档目录之前尝试填充列表。所以我试图[self.tableView reloadData];在方法结束时调用,viewDidLoad但我得到了相同的结果。

@implementation AppDelegate

- (void)createEditableCopyOfDatabaseIfNeeded
{
    //TESTING FOR EXISTENCE
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [searchPaths lastObject];
    NSString *writeableDBPath = [documentsDirectory stringByAppendingPathComponent:@"ScotchList.plist"];

    BOOL dbexists = [fileManager fileExistsAtPath:writeableDBPath];
    if (!dbexists) {
        // The writeable database does not exist, so copy the default to the appropriate location.
        NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"ScotchList.plist"];

        NSError *error;
        BOOL success = [fileManager copyItemAtPath:defaultDBPath toPath:writeableDBPath error:&error];
        if (!success) {
            NSAssert1(0, @"Failed to create writeable database file with message '%@'.", [error localizedDescription]);
        }
    }
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:@"MasterViewController_iPhone" bundle:nil];
        self.navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];

        self.window.rootViewController = self.navigationController;
    } else {
        MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:@"MasterViewController_iPad" bundle:nil];
        UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];

        DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController_iPad" bundle:nil];
        UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];

        masterViewController.detailViewController = detailViewController;

        self.splitViewController = [[UISplitViewController alloc] init];
        self.splitViewController.delegate = detailViewController;
        self.splitViewController.viewControllers = @[masterNavigationController, detailNavigationController];

        self.window.rootViewController = self.splitViewController;
    }
    [self.window makeKeyAndVisible];
    [self createEditableCopyOfDatabaseIfNeeded];
    [application setStatusBarStyle:UIStatusBarStyleBlackOpaque];
    return YES;
}

主视图控制器.m

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    self.sections = [[NSMutableDictionary alloc] init];
    BOOL found;

    // Loop through the whiskys and create our keys
    for (NSMutableDictionary *whisky in self.drinks)
    {
        NSString *c = [[whisky objectForKey:NAME_KEY] substringToIndex:1];

        found = NO;

        for (NSString *str in [self.sections allKeys])
        {
            if ([str isEqualToString:c])
            {
                found = YES;
            }
        }

        if (!found)
        {
            [self.sections setValue:[[NSMutableArray alloc] init] forKey:c];
        }
    }
    // Loop again and sort the whiskys into their respective keys
    for (NSMutableDictionary *whisky in self.drinks)
    {
        [[self.sections objectForKey:[[whisky objectForKey:NAME_KEY] substringToIndex:1]] addObject:whisky];
    }
    // Sort each section array
    for (NSString *key in [self.sections allKeys])
    {
        [[self.sections objectForKey:key] sortUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:NAME_KEY ascending:YES]]];
    }
        [self.tableView reloadData];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.582d0e
    self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
    self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:0x015/255.0 green:0x04/255.0 blue:0x04/255.0 alpha:1];
    self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"cellBackground.png"]];
    self.navigationItem.leftBarButtonItem = self.editButtonItem;
    self.navigationItem.leftBarButtonItem.tintColor = [UIColor redColor];
    self.navigationItem.backBarButtonItem.tintColor = [UIColor colorWithRed:0x3e/255.0 green:0x3e/255.0 blue:0x3e/255.0 alpha:1];
    UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];
    self.navigationItem.rightBarButtonItem = addButton;
    self.navigationItem.rightBarButtonItem.tintColor = [UIColor colorWithRed:0x015/255.0 green:0x04/255.0 blue:0x04/255.0 alpha:1];

    UIImage *titleImage = [UIImage imageNamed:@"whiskeyTitle.png"];
    self.navigationItem.titleView = [[UIImageView alloc]initWithImage:titleImage];

    NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [searchPaths lastObject];
    NSString *writeableDBPath = [documentsDirectory stringByAppendingPathComponent:@"ScotchList.plist"];

    NSMutableArray *tmpArray = [[NSMutableArray alloc]initWithContentsOfFile:writeableDBPath];

    self.drinks = tmpArray;
    deletedDrink = [[NSMutableArray alloc]init];
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(applicationDidEnterBackground:) 
                                                 name:UIApplicationDidEnterBackgroundNotification
                                               object:nil];

    //Register for application exiting information so we can save data
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(applicationWillTerminate:) name:UIApplicationWillTerminateNotification object:nil];

    bookCover = [[UIImageView alloc]init];
    bookCover.image = [UIImage imageNamed:@"Default.png"];
    openBookButton = [[UIButton alloc]init];
    [openBookButton addTarget:self action:@selector(goToPage:flipUp:) forControlEvents:UIControlEventTouchUpInside];
    bookCover.frame = CGRectMake(0, 0, 320, 480);
    openBookButton.frame = bookCover.frame;

    [self.navigationController.view addSubview:bookCover];
    [self.navigationController.view addSubview:openBookButton];
    [self.tableView reloadData];
}

好的更新

当应用程序最初构建并在手机上运行(安装)时,我已经NSLog()从 plist 中提取了我的数组,它记录为空。viewDidLoad如果我停止并重新构建并运行它会返回 plist 中的信息(非空)。

4

2 回答 2

1

知道了。基本上,我的appDelegate.m( createEditableCopyOfDatabaseIfNeeded) 中有一个方法可以检查文档目录中的数据库(在我的情况下是 plist)。如果已经有一个现有的 plist,它不会覆盖它。如果没有 plist,则它将我随应用程序附带的 plist 移动到文档目录。然后在applicationDidFinishLaunchingWithOptions:我调用的方法内部,[self createEditableCopyOfDatabaseIfNeeded];这看起来应该很好。然而,在applicationDidFinishLaunchingWithOptions方法内部有 if 语句来检查我在 if 和 else 检查 interfaceIdiom 之后currentDevice userInterfaceIdiom调用的内容。[self createEditableCopyOfDatabaseIfNeeded];我只是向上移动到userInterfaceIdiomiPhone 所在的 if 语句。

下面我评论了问题出在哪里以及我将它移到哪里来解决它。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:@"MasterViewController_iPhone" bundle:nil];
        self.navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];

        self.window.rootViewController = self.navigationController;

        //THIS WAS THE SOLUTION RIGHT BELOW.
        [self createEditableCopyOfDatabaseIfNeeded];
    } else {
        MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:@"MasterViewController_iPad" bundle:nil];
        UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];

        DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController_iPad" bundle:nil];
        UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];

        masterViewController.detailViewController = detailViewController;

        self.splitViewController = [[UISplitViewController alloc] init];
        self.splitViewController.delegate = detailViewController;
        self.splitViewController.viewControllers = @[masterNavigationController, detailNavigationController];

        self.window.rootViewController = self.splitViewController;
    }
    [self.window makeKeyAndVisible];
    //THIS IS WHERE [self createEditableCopyOfDatabaseIfNeeded]; WAS ORIGINALLY WHICH WAS CAUSING THE PROBLEM
    [application setStatusBarStyle:UIStatusBarStyleBlackOpaque];
    return YES;
}
于 2012-07-12T18:25:34.780 回答
0

您确定 plist 文件已加载并可在首次加载时访问。尝试这样的事情:

NSFileManager *filemgr;

filemgr = [NSFileManager defaultManager];

if ([filemgr fileExistsAtPath: @"/CacheDirectory/DocumentDirectory/TempDirectory/myfile.txt" ] == YES)
        NSLog (@"File exists");
else
        NSLog (@"File not found");

只想确认一下。如果存在,请尝试从中记录数据,以查看它是否在首次启动之前已完全填充,或者应用程序是否在文件完全在手机上打开之前打开了该文件。在模拟器中启动时,应用程序会尽快启动,并且可能会切换线程或导致文件写入在您的应用程序从中打开流之前无法完全完成...如果这是我想一想,在用户 iPhone 上安装它应该不会引起问题,因为应用程序不会在安装后立即启动。

无论如何,任何拥有 iPhone 并使用 facebook 应用程序的人都习惯于在打开应用程序时有时什么都没有出现,他们会重新启动它...... ;-)

于 2012-07-12T17:19:57.133 回答