核心数据:从sqlite数据库中获取数据时出现问题

时间:2011-01-20 02:16:09

标签: iphone core-data nsfetchrequest

我试图在表格视图中显示一些数据,这是标签栏控制器中视图控制器的一部分。目前我想在iPhone模拟器上运行该应用程序。我将sqlite数据库复制到以下位置 - / Users / {username} / Library / Application Support / iPhoneSimulator / 4.2 / Applications / {appid} / Documents

现在我正在尝试在视图控制器的viewWillAppear方法中获取数据。

#import "FugitivesViewController.h"    
#import "MyAppDelegate.h"

#import "Fugitive.h"

- (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
        NSManagedObjectContext *context = [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
        NSFetchRequest *request = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Fugitive" inManagedObjectContext:context];
        [request setEntity:entity];

        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
        [request setSortDescriptors:sortDescriptors];
        [sortDescriptors release];
        [sortDescriptor release];

        NSError *error = nil;
        NSMutableArray *mutableFetchResults = [[context executeFetchRequest:request error:&error] mutableCopy];

        if (mutableFetchResults == nil) {
            NSLog(@"Error while fetching the results");
        }

        self.items = mutableFetchResults;

        [mutableFetchResults release];
        [error release];

        [request release];
        [context release];
    }

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    return [self.items count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    Fugitive *fugitive = [items objectAtIndex:indexPath.row];
    cell.textLabel.text = fugitive.name;

    return cell;
}

问题是这在视图控制器中没有显示任何内容,也没有错误。我已经在tabbar控制器中连接了所需的插座。

检入调试器时,可变数组显示0个对象。我刚开始使用iOS开发。有人可以帮我弄清楚这里会出现什么问题吗?

更新 - 在Yuji的评论的帮助下,我检查了正在iPhone Simulator的Documents文件夹中复制的文件。它没有任何数据。这就是为什么视图没有显示数据的原因。因此问题似乎出现在我用于将文件从项目文件夹复制到应用程序文档文件夹的代码中。

这是怎么回事......

// MyAppDelegate.m
#import "MyAppDelegate.h"

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch.
    [self createEditableCopyOfDatabaseIfNeeded];

    [self.window addSubview:tabcontroller.view];
    [self.window makeKeyAndVisible];

    return YES;
}

- (void)createEditableCopyOfDatabaseIfNeeded {
    NSString *defaultDirectory = [[self applicationDocumentsDirectory] absoluteString];
    NSString *writableDBPath = [defaultDirectory stringByAppendingPathComponent:@"iBountyHunder1.sqlite"];

    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:writableDBPath]) {
        NSString *defaultDBPath = [[NSBundle mainBundle] pathForResource:@"iBountyHunder" ofType:@"sqlite"];
        if (defaultDBPath) {
            NSError *error;
            BOOL success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
            if (!success) {
                NSLog(@"The error is %@", [error localizedDescription]);
            }
        }
    }
}

无法理解为什么这不起作用????

5 个答案:

答案 0 :(得分:1)

您是否自己将sqlite3文件复制到Documents目录? 如果代码无法找到,那么代码会将可写数据库副本创建到Documents目录。

执行以下操作。

  1. 在Xcode中运行项目
  2. 按iPhone模拟器上的主页按钮
  3. 删除iBountyHunter
  4. 退出模拟器
  5. 再次运行项目

答案 1 :(得分:1)

我刚刚注意到您已在上面的一个代码段中命名了您的数据库“iBountyHunder”以及“iBountyHunder1”。 Head First提供的文件是“iBountyHunter”(t,最后不是d)。

您可能希望检查项目名称是否与db文件名一致,因为核心数据模板希望它们完全相同。

当我让数据库正常工作时,我发现每次使用Build都有帮助 - >清除所有目标以及iPhoneSimulator - >重置内容和设置...

答案 2 :(得分:1)

我在尝试按照本书中的代码时遇到了同样的错误。检查了可写路径上的可用数据库,并检查了两个.sqlite文件的内容, 我发现数据库的名称应该与项目名称匹配。查看您的import语句,看起来您将项目命名为My。因此,应使用My.sqlite作为文件名复制数据库。我已经在我的macbook上试过了,它确实有效。

仅供参考,我使用sqlite database browser检查.sqlite文件的内容。

答案 3 :(得分:0)

您的课程以#import "MyAppDelegate.h"开头,这让我怀疑它是您的应用委托,而不是视图控制器。如果它不是视图控制器,那么我认为- (void)viewWillAppear:(BOOL)animated不会运行。尝试在该方法中加入NSLog(@"this code is being run");以查看它是否正在执行。

答案 4 :(得分:0)

我下载了第7章的代码示例。我在XCode中打开了它,并将Project-> Edit Project Settings-> Base SDK更新为最新的sdk(4.2)。如果计划是从头开始创建一个新项目,请确保它由Core Data支持,并且正确复制和粘贴其项目中的代码。