DB Wrapper没有响应消息?

时间:2009-04-27 17:17:16

标签: iphone objective-c sqlite

我正在为iphone-sdk 2.2.1开发(所以没有CoreData cry )。

所以我使用的是FMDatabase project,它只是Obj C中的一个SQLite Wrapper。我的App在从AppDelegate与它交互时工作得很好。我已经测试了AppDelegate中的连接,插入等。

现在,我有一个数据对象,我想存储到数据库中。我希望从ViewController类发生此事件。让我们看一些代码:

App Delegate在applicationDidFinishLaunching方法中创建数据库。 DB被声明为此类的属性,因此我可以轻松访问它。

db = [FMDatabase databaseWithPath:[self getDBPath]];

这很好,我已经测试过了。我唯一关心的是'db'是这个类的属性。这应该不会引起问题,是吗?

从同一个applicationDidFinishLaunching方法中,我测试了一个简单的插件可以使用。这个作品:

[db beginTransaction];
[db executeUpdate:@"INSERT INTO tblDataSamples (...) VALUES (...);"];
[db commit];

现在,如果我只是采用这个确切的代码并将其移动到AppDelegate的实例方法,则代码将不再起作用。当我们点击[db beginTransaction]行时,我收到"EXC_BAD_ACCESS"错误。

此代码对此调用的流程: - AltViewController接收按钮点击事件 - AltViewController告诉ApplicationDelegate执行“addSample”方法。 - ApplicationDelegate的addSample方法在[db beginTransaction]上失败。

既然我已经写完了,我认为问题是我的数据库在ApplicationDelegate加载RootView后丢失了。也许我错了。有人有什么想法吗?

!!!!!!!!!

更新<!/强> 我刚刚修改了addSample方法以包含

db = [FMDatabase databaseWithPath:[self getDBPath]];
    if (![db open]) {
        NSLog(@"Could not open db.");
    }

[db close];

现在整个交易都有效。因此,新问题是:如何使数据库在ONCE中打开并在不同视图和viewControllers之间保持开放状态?

1 个答案:

答案 0 :(得分:2)

您遇到了麻烦,因为您还不知道内存管理规则。在这种情况下,databaseWithPath:方法返回一个自动释放的对象,该对象在运行循环结束时被丢弃。您的数据库指针仍然指向该无效的内存位置,这就是为什么当您稍后尝试访问它时,您会看到EXC_BAD_ACCESS错误。

好消息是内存管理实际上很容易在Cocoa中学习。看看this page的初学者,它应该有足够的信息让你前进。要解决这个特殊问题,你需要在db对象创建后调用retain方法,并在不再需要它时释放它(如果你在应用程序的生命周期中保留它,则没有任何东西可以获得释放它,但它仍然是很好的做法)。