Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 数据库包装器没有响应消息?_Iphone_Objective C_Sqlite - Fatal编程技术网

Iphone 数据库包装器没有响应消息?

Iphone 数据库包装器没有响应消息?,iphone,objective-c,sqlite,Iphone,Objective C,Sqlite,我正在为iphonesdk2.2.1开发(所以没有CoreData) 所以我使用的是,它只是Obj C中的一个SQLite包装器。当从AppDelegate与DB交互时,我的DB工作得很好。我已经从AppDelegate测试了连接、插入等 现在,我有一个数据对象要存储到数据库中。我希望此事件在ViewController类中发生。让我们看一些代码: App Delegate在ApplicationIDFinishLaunching方法中创建DB。DB被声明为这个类的一个属性,所以我可以很容易地访

我正在为iphonesdk2.2.1开发(所以没有CoreData)

所以我使用的是,它只是Obj C中的一个SQLite包装器。当从AppDelegate与DB交互时,我的DB工作得很好。我已经从AppDelegate测试了连接、插入等

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

App Delegate在ApplicationIDFinishLaunching方法中创建DB。DB被声明为这个类的一个属性,所以我可以很容易地访问它

db = [FMDatabase databaseWithPath:[self getDBPath]];
这个很好用,我已经测试过了。我唯一有点担心的是'db'是类的一个属性。这不应该引起问题,对吗

从相同的ApplicationIDFinishLaunching方法中,我已经测试了一个简单的insert是否可以使用。这项工作:

[db beginTransaction];
[db executeUpdate:@"INSERT INTO tblDataSamples (...) VALUES (...);"];
[db commit];
现在,如果我简单地将这段代码移到AppDelegate的实例方法中,代码就不再有效了。当我们点击[db beginTransaction]行时,我得到一个
“EXC\u BAD\u ACCESS”
错误

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

现在我已经写出来了,我想问题是在ApplicationLegate加载RootView之后,我的DB丢失了。也许我错了。有人有什么想法吗

更新 我刚刚修改了addSample方法,将


整个事务现在可以工作了。因此,新的问题是:如何使数据库打开一次,并在不同的视图和视图控制器之间保持打开状态?

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


好消息是,在Cocoa中,内存管理实际上非常容易学习。首先看一看,它应该有足够的信息让你去。要解决这个特殊问题,您需要在db对象创建后调用
retain
方法,并在不再需要时释放它(如果您在应用程序的生命周期中一直保留它,那么释放它并没有什么好处,但这仍然是一个很好的做法)。

那么,与db交互的更好方法是什么呢?每次要执行事务时打开和关闭它,还是在应用程序的生命周期内保持它打开?现在,我每次都打开和关闭,因为我没有+1到db的保留计数。在创建时将其保留在我的AppDelegate中是否更好?另外,将DB声明为静态是否有益?我将首先将DB实例放在一个全局应用程序生命周期控制器(如应用程序控制器)中,但最终的设计应取决于您自己的设计和性能考虑。只使用Sqlite3 API可能更容易。它非常简单和简洁。您可以轻松地为实际使用的函数创建对象包装器/便利设备。可以使用db=[[FMDatabase databaseWithPath…]retain]或[self-setDb:[FMDatabase databaseWithPath…]],其中db设置为具有“retain”属性的属性
db = [FMDatabase databaseWithPath:[self getDBPath]];
    if (![db open]) {
        NSLog(@"Could not open db.");
    }
[db close];