【问题标题】:Core Data: Issue in fetching data from sqlite database核心数据:从 sqlite 数据库中获取数据的问题
【发布时间】:2011-01-20 02:16:09
【问题描述】:

我正在尝试在表格视图中显示一些数据,该表格视图是选项卡栏控制器中视图控制器的一部分。目前我正在尝试在 iPhone Simulator 上运行该应用程序。我将 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;
}

问题是这在视图控制器中什么都没有显示,也没有错误。我已经在标签栏控制器中连接了所需的插座。

在调试器中检查,可变数组显示 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]);
            }
        }
    }
}

不明白为什么这不起作用????

【问题讨论】:

  • 你是如何创建 sqlite 数据库的?
  • @Yuji - 我正在学习 Head First iPhone Development 的教程 - 从这里复制 sqlite 数据库 headfirstlabs.com/iphonedev - 第 7 章
  • 在 viewWillAppear 中释放托管应用程序上下文是不正确的。检索到对象的指针,但从未取得所有权。
  • 错误也是如此。由于从未获得所有权,因此无需释放它。请参阅部分:“引用返回的对象”:developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/…
  • @Evan - 那么,我应该什么时候释放这些指针?在viewWillDisappear() 方法中?

标签: iphone core-data nsfetchrequest


【解决方案1】:

sqlite3文件是自己拷贝到Documents目录下的吗? 如果在 Documents 目录中找不到,该代码会创建可写的数据库副本。

执行以下操作。

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

【讨论】:

    【解决方案2】:

    我刚刚注意到您在上面的代码 sn-ps 中将您的数据库命名为“iBountyHunder”以及“iBountyHunder1”。 Head First 提供的文件是“iBountyHunter”(最后是 t,而不是 d)。

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

    当我让数据库正常工作时,我还发现每次使用 Build -> Clean All Targets 以及 iPhoneSimulator -> Reset Contents and Settings... 都有帮助...

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

          • 这里错过了复制一行。我已经编辑了视图控制器的类导入。上面的代码只是视图控制器。我正在导入MyAppDelegate.h 以获取对managedObjectContext 的引用。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-01
          • 2011-10-22
          • 2011-10-07
          相关资源
          最近更新 更多