【问题标题】:Data not being saved to core data数据未保存到核心数据
【发布时间】:2013-09-24 04:46:57
【问题描述】:

我正在使用专门为 iOS 7 编译的 Xcode 5。

我正在从 UTF8 txt 文件中读取数据以填充核心数据实体。读取数据后,我将其记录到控制台。数据在那里。我填充实体并将实体记录到控制台。我保存它。没有错误。没有崩溃。

我在设备上看到 3 个文件:

  • MyDatabase.sqlite
  • MyDatabase.sqlite-shm
  • MyDatabase.sqlite-wal

当应用程序启动并且MyDatabase.sqlite 被创建为空时,它有 40 kb。此时shm文件为32kb,wal文件为零。

在我将数据写入数据库后,wal 文件增长到 1.7 Mb,但其他两个文件保持其初始大小,或者换句话说,数据没有保存到数据库中。我已经通过使用外部数据库查看器检查 sqlite 文件确认了这一点。

这是我正在使用的代码:

// NSArray *arrayOfYears = ... 
// this contains an array of numbers read from the CSV file
// at this point the array contains numbers in text format

// NSArray *arrayOfBrands = ...
// this is an array of brands

for (int i=0; i<[arrayOfBrands count]; i++) {

            Cars *car = [NSEntityDescription insertNewObjectForEntityForName:@"Cars" inManagedObjectContext:context];

            car.brand = [arrayOfBrands objectAtIndex:i];
            car.year = [NSNumber numberWithInt:[[arrayOfYears objectAtIndex:i] integerValue]];

            NSError *error = nil;
            if (![context save:&error]) {
                // Handle the error.
                NSLog(@"error = %@", error);
            }
}

这不会产生错误或崩溃。它就像是在节省。我已将 mySql 调试级别提高到 3,这就是我在控制台上看到的...

创建空表时

CoreData: annotation: Connecting to sqlite database file at "/var/mobile/Applications/BB22334C4-550A-4C44-B17A-3F02062EC687/Documents/MyDatabase.sqlite"
CoreData: annotation: creating schema.
CoreData: sql: pragma page_size=4096
CoreData: sql: pragma auto_vacuum=2
CoreData: sql: BEGIN EXCLUSIVE
CoreData: sql: SELECT TBL_NAME FROM SQLITE_MASTER WHERE TBL_NAME = 'Z_METADATA'
CoreData: sql: CREATE TABLE ZCARS ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, ZYEAR INTEGER, ZBRAND VARCHAR ) 
CoreData: annotation: Creating primary key table.
CoreData: sql: CREATE TABLE Z_PRIMARYKEY (Z_ENT INTEGER PRIMARY KEY, Z_NAME VARCHAR, Z_SUPER INTEGER, Z_MAX INTEGER)
CoreData: sql: INSERT INTO Z_PRIMARYKEY(Z_ENT, Z_NAME, Z_SUPER, Z_MAX) VALUES(1, 'Cars', 0, 0)
CoreData: sql: CREATE TABLE Z_METADATA (Z_VERSION INTEGER PRIMARY KEY, Z_UUID VARCHAR(255), Z_PLIST BLOB)
CoreData: sql: SELECT TBL_NAME FROM SQLITE_MASTER WHERE TBL_NAME = 'Z_METADATA'
CoreData: sql: DELETE FROM Z_METADATA WHERE Z_VERSION = ?
CoreData: details: SQLite bind[0] = 1
CoreData: sql: INSERT INTO Z_METADATA (Z_VERSION, Z_UUID, Z_PLIST) VALUES (?, ?, ?)
CoreData: details: SQLite bind[0] = 1
CoreData: details: SQLite bind[1] = "C6E2268B-6792-4298-B292-5025E5BDE31A"
CoreData: details: SQLite bind[2] = <NSData len=455>
CoreData: annotation: Saving new meta data; version = 1 ; UUID = C6E2268B-6792-4298-B292-5025E5BDE31A
CoreData: sql: COMMIT
CoreData: sql: pragma journal_mode=wal
CoreData: sql: pragma journal_mode=wal
CoreData: sql: pragma cache_size=200
CoreData: sql: SELECT Z_VERSION, Z_UUID, Z_PLIST FROM Z_METADATA

每年保存一个品牌后

CoreData: sql: BEGIN EXCLUSIVE
CoreData: sql: SELECT Z_MAX FROM Z_PRIMARYKEY WHERE Z_ENT = ?
CoreData: annotation: getting max pk for entityID = 4
CoreData: sql: UPDATE Z_PRIMARYKEY SET Z_MAX = ? WHERE Z_ENT = ? AND Z_MAX = ?
CoreData: annotation: updating max pk for entityID = 4 with old = 0 and new = 1
CoreData: sql: COMMIT
CoreData: sql: BEGIN EXCLUSIVE
CoreData: sql: INSERT INTO ZTABULEIRO(Z_PK, Z_ENT, Z_OPT, ZYEAR, ZBRAND) VALUES(?, ?, ?, ?, ?)
CoreData: details: SQLite bind[0] = (int64)1
CoreData: details: SQLite bind[1] = (int64)4
CoreData: details: SQLite bind[2] = (int64)1
CoreData: details: SQLite bind[3] = "FORD"
CoreData: details: SQLite bind[4] = (int64)1989
CoreData: sql: COMMIT
CoreData: annotation: Changing objectID 0x14e71730 <x-coredata:///Cars/t38FA86EE-4124-4FD7-A8C0-8CE7BBAC73782> to 0x14e73ef0 <x-coredata://C6E3368B-6792-4298-B292-5025E5BDE31A/Cars/p1>
CoreData: sql: pragma page_count
CoreData: annotation: sql execution time: 0.0014s
CoreData: sql: pragma freelist_count
CoreData: annotation: sql execution time: 0.0016s

我在这里看到的一件奇怪的事情是像 int64 这样的年份变量,当我将它定义为整数 16 时。为什么它使用整数 64 超出了我的理解......

根本没有保存数据。数据在那里。如果我将数据数组记录到控制台,我会看到数据。如果我在保存之前记录填充的实体,我会看到数据。

我正在运行 iOS 7 的设备上对此进行测试。谢谢。

我错过了什么?我该如何调试?

【问题讨论】:

  • 你有多少个 NSManagedObjectContexts?这个特定的上下文是否与 NSPersistentStoreCoordinator 相关联?
  • 据我所知,一个。你为什么这么问?有没有办法拥有多个?目的是什么?
  • 如果您在父子关系中有多个上下文,则只保存上一级。保存到文件仅通过保存根上下文触发。如果您只有一个上下文,则不适用。
  • 你所说的对我来说是克林贡语,但据我所知,我只有一个上下文。
  • 你能显示你设置持久存储的代码吗?

标签: iphone ios ipad cocoa-touch core-data


【解决方案1】:

如果预写日志 (wal) 的大小增加,则将数据保存到数据库中,请参阅此处的文档 http://www.sqlite.org/draft/wal.html。你用什么打开数据库文件?您必须使用适用于 WAL 日志模式的工具。与其直接查看 db 文件,不如尝试创建一个新的上下文并获取您保存的实体。

【讨论】:

  • 你是对的!我正在独立检查 sqlite 文件。当我将其他两个文件复制到同一目录并再次检查数据库时,数据库显示已填充。现在这是所有问题的大问题:当应用程序第一次启动时,它必须将 sqlite 文件从包复制到文档目录。我现在该怎么办?将捆绑包中的所有 3 个文件复制到文档目录?数据库现在不只是一个,而是 3 个文件?哇!或者换句话说:我必须将这 3 个文件包含在包中,对吗?
  • 或另一种选择:有一种方法可以在核心数据上禁用这个 wal 东西或将更改提交到 sqlite 文件?谢谢
  • 是的。看到这个帖子stackoverflow.com/questions/18870387/…
  • 为什么要移动文件?您是否使用预填充的数据库进行部署?
  • 是的。谢谢,我已经设法禁用了这个日志,现在总数据库有 128 kb 而不是 3.3 MB !!!!!!!!!!!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多