2009-04-27 51 views
1

我正在开发iphone-sdk 2.2.1(所以没有CoreData cry)。DB包装器无法响应消息?

所以我使用的是FMDatabase project,它只是Obj C中的一个SQLite包装器。我的数据库在与我的AppDelegate进行交互时运行良好。我已经从AppDelegate测试了连接,插入等。

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

应用程序委托在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中打开?

+0

使用Sqlite3 API可能会更容易。它非常简单和简洁。您可以轻松地为您实际使用的功能创建对象包装器/便利。 – 2009-04-28 00:27:42

+0

使用db = [[FMDatabase databaseWithPath ...] retain]或[self setDb:[FMDatabase databaseWithPath ...]],其中db设置为具有“retain”属性的属性 – lostInTransit 2009-04-28 04:38:57

回答

2

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

好消息是内存管理其实很容易在Cocoa学习。首先看看this page,它应该有足够的信息让你走。为了解决这个特殊的问题,你需要在db对象创建后调用retain方法,并在不再需要的时候释放它(如果你在应用程序的整个生命周期中保留它,没有什么能够释放它,但是这仍然是一个好习惯)。