Ios fmdb路径和从另一个viewController第二次使用db
我正在使用下面的代码在一个类中创建db,并在viewController中使用它,在newViewController的另一个类中再次使用相同的代码。Ios fmdb路径和从另一个viewController第二次使用db,ios,ios6,fmdb,Ios,Ios6,Fmdb,我正在使用下面的代码在一个类中创建db,并在viewController中使用它,在newViewController的另一个类中再次使用相同的代码。 对吗?或者,它是否在其位置创建新的数据库,或者在存在现有数据库的情况下使用新的数据库 还是只需要使用路径 当我在下面的示例中尝试extern NSString*path时,我收到了中文字母,无法打开它 基本上,在第二个控制器中,我只读取数据。 所以我试图通过path访问db,数据库的path和数据库是打开的 如果我已经使用下面的代码创建了它,并且
对吗?或者,它是否在其位置创建新的数据库,或者在存在现有数据库的情况下使用新的数据库 还是只需要使用路径 当我在下面的示例中尝试
extern NSString*path
时,我收到了中文字母,无法打开它
基本上,在第二个控制器中,我只读取数据。所以我试图通过path访问db,数据库的path和数据库是打开的 如果我已经使用下面的代码创建了它,并且我想从另一个ViewController第二次打开它,该怎么办。
请帮忙。
提前谢谢 在第一控制器中:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *path = [docsPath stringByAppendingPathComponent:@"test.db"];
FMDatabase *database;
database = [FMDatabase databaseWithPath:path];
[database open];
[database executeUpdate:@"DROP TABLE IF EXISTS **"];
[database executeUpdate:@"CREATE TABLE "];
//Select query for single row
FMResultSet *s = [database executeQuery:@"SELECT COUNT(*) FROM table"];
if ([s next]) {
int Count = [s intForColumnIndex:0];
}
//DO Something
[database close];
以上代码在viewcontroller 1中运行良好
我在视图控制器2中尝试过的东西,但仍然不起作用
extern NSString *path;
FMDatabase *database;
database = [FMDatabase databaseWithPath:path];
[database open];
我在这里得到一个错误,因为路径是在什么看起来像中文
错误为EXC\U BAD\U访问代码
还通过以下方式尝试了全局数据库:
extern FMDatabase *database;
并将其用作
[database open];
我仍然会犯同样的错误
最后,它在第二个控制器中使用了以下代码。
我只是想看看这是不是正确的方法,或者我可以使用db open之类的工具。
但是我试过了,但它不起作用。而且我也没有使用任何错误处理程序,因为我不知道如何在FMDB中执行此操作。
提前谢谢
请让我知道以下实现是否正确:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *newpath = [docsPath stringByAppendingPathComponent:@"test.db"];
FMDatabase *database2 ;
database2 = [FMDatabase databaseWithPath:newpath];
[database2 open];
//DO Something
[database2 close];
你应该把数据库路径定义为全局变量,第一次使用关闭操作,第二次使用打开时间,打开数据库时,它会自动判断是否有数据库,如果没有会自动创建。如果有,它会直接打开数据库。用于判断数据库打开是否成功:
if(![db open]){
//错误
返回;
}
//一些手术
/ /...
[db close]代码>作为应如何检查FMDB方法成功的示例,以下是一个示例:
#import "FMDatabase.h"
#import "FMDatabaseAdditions.h"
- (void)performDatabaseDemonstration
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *path = [docsPath stringByAppendingPathComponent:@"test.db"];
// open db
FMDatabase *database = [FMDatabase databaseWithPath:path];
FMResultSet *rs;
if ([database open])
{
// drop table
if (![database executeUpdate:@"DROP TABLE IF EXISTS test"])
NSLog(@"%s: drop error: %@", __FUNCTION__, [database lastErrorMessage]);
// create table
if (![database executeUpdate:@"CREATE TABLE test(col1 INTEGER, col2 TEXT)"])
NSLog(@"%s: create error: %@", __FUNCTION__, [database lastErrorMessage]);
// insert a row of data
if (![database executeUpdate:@"INSERT INTO test VALUES(1, 'Rob')"])
NSLog(@"%s: insert 1 error: %@", __FUNCTION__, [database lastErrorMessage]);
// insert another row of data
if (![database executeUpdate:@"INSERT INTO test VALUES(2, 'Rachel')"])
NSLog(@"%s: insert 2 error: %@", __FUNCTION__, [database lastErrorMessage]);
// Select query for single row
if (!(rs = [database executeQuery:@"SELECT count(*) FROM test"]))
NSLog(@"%s: select error: %@", __FUNCTION__, [database lastErrorMessage]);
if ([rs next]) {
int count = [rs intForColumnIndex:0];
NSLog(@"%s: count = %d", __FUNCTION__, count);
}
[rs close];
// if getting single value from single row, you can use FMDatabaseAdditions.h methods:
NSInteger count2 = [database intForQuery:@"SELECT col1, col2 FROM test"];
NSLog(@"%s: count2 = %d", __FUNCTION__, count2);
// let's actually retrieve data
if (!(rs = [database executeQuery:@"SELECT col1, col2 FROM test"]))
NSLog(@"%s: select error: %@", __FUNCTION__, [database lastErrorMessage]);
while ([rs next]) {
NSLog(@"%s: col1 = %@; col2 = %@", __FUNCTION__, [rs objectForColumnIndex:0], [rs objectForColumnIndex:1]);
}
[rs close];
//close
[database close];
}
else
{
NSLog(@"%s: open error: %@", __FUNCTION__, [database lastErrorMessage]);
}
}
关于如何从不同的控制器打开数据库,有很多选项。但我可能会建议,除了从两个控制器中检索一些共享路径/文件名变量之外,您可能还希望在对象中不仅封装文件名,还封装共享的FMDB代码
就个人而言,每当我发现自己在两个不同的控制器中编写相同或相似的代码时,我都会问自己是否要将代码抽象到自己的类中。例如,在本例中,我不会讨论这两个类如何访问数据库文件名,而是创建自己的模型对象(一个NSObject
子类),用于封装SQL、打开数据库等。然后我可以让我的两个视图控制器从该方法对象调用方法,并且真正地减少了文件名中的冗余,也减少了代码本身中的冗余。例如,创建数据库路径、打开数据库、检查打开是否成功等都是相同的。那么,为什么不在某个模型对象中使用一个方法,它可以为您完成所有这些工作呢
要使此模型对象可从两个控制器访问,您有一系列选项:
- 将其作为第一个视图控制器的属性,并在
prepareforsgue
期间将其传递给第二个控制器
- 为它创建一个单例对象;或
- 将其作为应用程序委托的属性,两个控制器都可以从中获取该属性
在其他控制器中打开数据库时,它不会创建新数据库。因此,在一个或另一个控制器中如何打开/使用肯定存在问题。您必须向我们展示更多的代码来诊断问题。您是否正在检查所有FMDB呼叫的返回码,以确保所有呼叫都成功运行?例如,您通常会有if(![datatabase2 open]){NSLog(“open failed:%@,[datatabase2 lastErrorMessage]);}
和if(![database2 executeUpdate:sql]){NSLog(“Execute failed:%@,[datatabase2 lastErrorMessage]);}
,等等@Rob谢谢你,先生。我编辑了上面的代码,解释了我正在使用的代码和流程。如果你还需要了解我可能在哪里犯了错误/实现了代码,请告诉我。再次感谢你,先生,感谢你的时间和努力。另外,我没有对所有的FMDB调用使用返回码。因为我不知道怎么做。此外,错误是给出错误,说明使用了未声明的变量。谢谢先生。我有几个疑问:NSArray*path=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);NSString*docsPath=[path objectAtIndex:0];NSString*path=[docsPath stringByAppendingPathComponent:@“test.db”];//open db FMDatabase*database=[FMDatabase databaseWithPath:path];如果db不存在,但使用它,则此代码是否创建db。正确的?因为这就是我在代码中使用的方式。如果是,那么我将在第一视图控制器中创建一个用于检查和创建db的方法,并从第二个控制器调用相同的方法,对吗?如果上述方法不正确,请编写代码解释。谢谢。我还需要使用[rs close];也因为我只使用了[db close];到目前为止。我想这可能是个错误。你认为呢?@JacobWood我们已经超出了原始问题的范围,所以我建议将此迁移到聊天: